a
    YÒOc=  ã                   @   sÜ   d dl Z d dlZd dlmZ d dlmZ d dlmZmZ d dl	m
Z
mZ d dlmZ d dlmZmZmZmZ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 d dl m!Z! d dl"m#Z# G dd„ deƒZ$dS )é    N)Údefaultdict)ÚDecimal)ÚIPv4AddressÚIPv6Address)ÚObjectDoesNotExistÚValidationError©Úcall_command)ÚDEFAULT_DB_ALIASÚIntegrityErrorÚ
connectionÚconnectionsÚmodels)ÚMigrationExecutor)Úatomic)ÚCountry)Úresource)Ú	InterfaceÚreftag_to_cls)Ú__version__)Úconcretec                   @   sˆ  e Zd ZeeeefZej	e
j	eje
jeje
jeje
jeje
jeje
jeje
jeje
jeje
jeje
ji
ZddgidddgidœZedd„ ƒZedd	„ ƒZed8dd„ƒZed9dd„ƒZedd„ ƒZedd„ ƒZedd„ ƒZ ed:dd„ƒZ!edd„ ƒZ"edd„ ƒZ#edd„ ƒZ$edd„ ƒZ%edd „ ƒZ&ed!d"„ ƒZ'd#d$„ Z(d%d&„ Z)d'd(„ Z*d)d*„ Z+d+d,„ Z,d-d.„ Z-d/d0„ Z.d;d2d3„Z/e0fd4d5„Z1d6d7„ Z2d
S )<ÚBackendÚunique)z6Duplicate entry '[^\']+' for key '(?P<field_name>\w+)'é   )z4UNIQUE constraint failed: (\w+)\.(?P<field_name>\w+)r   )z(column (?P<field_name>\w+) is not uniquer   )ÚmysqlZsqlitec                 C   s4   t jD ](}|jjD ]}|jdv rd|_d|_qqd S )N)ÚcreatedÚupdatedF)r   Z
all_modelsÚ_metaÚfieldsÚnameZauto_now_addZauto_now)ÚclsÚmodelÚfield© r#   ú^/var/www/html/gsl.tools/lib/python3.9/site-packages/django_peeringdb/client_adaptor/backend.pyÚsetup:   s
    

zBackend.setupc                 C   s   t ƒ S ©N)Úatomic_transaction)r    r#   r#   r$   r'   E   s    zBackend.atomic_transactionNc                 C   s   t S r&   )r   ©r    r   r#   r#   r$   Úvalidation_errorI   s    zBackend.validation_errorc                 C   s   |r
|j S tS r&   )ZDoesNotExistr   r(   r#   r#   r$   Úobject_missing_errorM   s    zBackend.object_missing_errorc                 C   s$   |j  ¡ }|r tt | ¡ ¡ƒS dS )Nr   )Z	handlerefÚlast_changeÚintÚcalendarÚtimegmÚ	timetuple)Úselfr   Zupdr#   r#   r$   r+   S   s    
zBackend.last_changec                 C   s   |j j|d�S )N)Úpk©ÚobjectsÚget)r0   r   Úidr#   r#   r$   Ú
get_objectZ   s    zBackend.get_objectc                 C   s   |j jf i ||i¤ŽS r&   r2   ©r0   r   Ú
field_nameÚvaluer#   r#   r$   Úget_object_by^   s    zBackend.get_object_byc                 C   s   |r|j j|d�S |j  ¡ S )N)Zpk__in)r3   ÚfilterÚall)r0   r   Zidsr#   r#   r$   Úget_objectsb   s    zBackend.get_objectsc                 C   s   |j jf i ||i¤ŽS r&   )r3   r;   r7   r#   r#   r$   Úget_objects_byh   s    zBackend.get_objects_byc                 K   s   |j jf i |¤ŽS r&   )r3   Úcreate)r0   r   Údatar#   r#   r$   Úcreate_objectl   s    zBackend.create_objectc                 C   s
   |j  ¡ S r&   )r   Ú
get_fields)r0   r   r#   r#   r$   rB   p   s    zBackend.get_fieldsc                 C   s   |j  |¡S r&   )r   Ú	get_field©r0   r   r8   r#   r#   r$   rC   t   s    zBackend.get_fieldc                 C   s   |j  |¡jS r&   )r   rC   Úrelated_modelrD   r#   r#   r$   Úget_field_concretex   s    zBackend.get_field_concretec                 C   s,   |   ||¡}t|ddƒ}t|ddƒ}||fS )NrE   FÚmultiple)rC   Úgetattr)r0   r   r8   r"   ÚrelatedrG   r#   r#   r$   Úis_field_related|   s    zBackend.is_field_relatedc                 C   s0   t ||ƒ}t|dƒr | |¡ nt|||ƒ dS )z%Set a many-to-many field on an objectÚsetN)rH   ÚhasattrrK   Úsetattr)r0   Úobjr8   ZobjsZrelationr#   r#   r$   Úset_relation_many_to_manyƒ   s    

z!Backend.set_relation_many_to_manyc                 C   s   |  ¡  d S r&   )Z
full_clean©r0   rN   r#   r#   r$   Úclean‹   s    zBackend.cleanc                 C   s   |  ¡  d S r&   )ÚsaverP   r#   r#   r$   rR   Ž   s    zBackend.savec                 C   s>   |j  |¡}t|tjƒr6t|tƒr6tdj||jd�ƒS |S d S )Nz{:.{prec}f})Úprec)	r   rC   Ú
isinstancer   ZDecimalFieldÚfloatr   ÚformatZdecimal_places)r0   r   r8   r9   r"   r#   r#   r$   Úconvert_field‘   s    zBackend.convert_fieldc           
      C   sl   t tƒ}t|j ¡ ƒD ]P\}}d}t |t|ƒ¡}|r|j 	|¡}|  
|j¡}	||	  t| d¡ƒ¡ q|S )z|
        Parse error messages and collect the missing-relationship errors
        as a dict of Resource -> {id set}
        z!.+ with id (\d+) does not exist.+r   )r   rK   ÚlistÚ
error_dictÚitemsÚreÚmatchÚstrr   rC   Zget_resourcerE   Úaddr,   Úgroup)
r0   rN   ÚexcÚmissingr   ÚerrÚpatternÚmr"   Úresr#   r#   r$   Údetect_missing_relations˜   s    z Backend.detect_missing_relationsc                 C   sh   d}g }t |tƒr|  |¡S t |tƒs.J tƒ‚t|j ¡ ƒD ]"\}}t 	|t
|ƒ¡r<| |¡ q<|pfdS )z�
        Parse error, and if it describes any violations of a uniqueness constraint,
        return the corresponding fields, else None
        z$(\w+) with this (\w+) already existsN)rT   r   Ú_detect_integrity_errorr   Ú	TypeErrorrX   rY   rZ   r[   Úsearchr]   Úappend)r0   r`   rc   r   r   rb   r#   r#   r$   Údetect_uniqueness_error¨   s    

zBackend.detect_uniqueness_errorc                 C   sb   t j}| j| }t|tƒsJ ‚| d¡D ]4\}}t |t|j	| ƒ¡}|r(| 
¡ d g  S q(d S )Nr   r8   )r   ÚvendorÚERROR_PATTERNSrT   r   r4   r[   ri   r]   ÚargsÚ	groupdict)r0   r`   ZengineÚpatternsrc   Úindexrd   r#   r#   r$   rg   ¹   s    
zBackend._detect_integrity_errorr   c                 C   s   t dd|d� d S )NZmigrateF©ÚinteractiveÚ	verbosityr   )r0   rt   r#   r#   r$   Úmigrate_databaseÇ   s    zBackend.migrate_databasec                 C   s0   t | }| ¡  t|ƒ}|jj ¡ }| |¡ S r&   )r   Zprepare_databaser   ÚloaderÚgraphZ
leaf_nodesZmigration_plan)r0   Zdatabaser   ÚexecutorÚtargetsr#   r#   r$   Úis_database_migratedË   s
    zBackend.is_database_migratedc                 C   s   t dddd� d S )NÚflushFr   rr   r   )r0   r#   r#   r$   Ú
delete_allÓ   s    zBackend.delete_all)N)N)N)r   )3Ú__name__Ú
__module__Ú__qualname__r   r   r   r   ZCUSTOM_FIELDSr   ZFacilityr   ZInternetExchangeZInternetExchangeFacilityZInternetExchangeLanZIXLanZInternetExchangeLanPrefixZIXLanPrefixZNetworkZNetworkContactZNetworkFacilityZNetworkIXLanZOrganizationZRESOURCE_MAPrm   Úclassmethodr%   r'   r)   r*   r   r+   r6   r:   r=   r>   rA   rB   rC   rF   rJ   rO   rQ   rR   rW   rf   rk   rg   ru   r
   rz   r|   r#   r#   r#   r$   r      s|   ü	öÿþÿü












r   )%r-   r[   Úcollectionsr   Údecimalr   Ú	ipaddressr   r   Zdjango.core.exceptionsr   r   Zdjango.core.managementr	   Z	django.dbr
   r   r   r   r   Zdjango.db.migrations.executorr   Zdjango.db.transactionr   r'   Zdjango_countries.fieldsr   Z	peeringdbr   Zpeeringdb.backendr   r   Zdjango_peeringdbr   Zdjango_peeringdb.modelsr   r   r#   r#   r#   r$   Ú<module>   s   