
    [jg              
         U d Z ddlmZ ddlmZ ddlmZmZmZ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mZ dd
lmZ ddlmZ ddlmZ ddl m!Z!  G d de          Z" e" e#d           Z$e$j%        e$j&        fZ'de(d<   eee         gee         f         Z) G d d          Z*ej+        e$j&        ej,        e$j-        ej.        e$j/        ej0        e$j/        ej1        e$j/        iZ2d.dZ3d/dZ4d0d&Z5d1d(Z6d2d*Z7d3d,Z8d-S )4z*Represent a deployment of MongoDB servers.    )annotations)sample)AnyCallableListMappingMutableMapping
NamedTupleOptionalcastMinKey)ObjectId)common)ConfigurationError)ReadPreference_AggWritePref_ServerModeServerDescription)	Selection)SERVER_TYPE)_Addressc                  L    e Zd ZU ded<   ded<   ded<   ded<   ded<   ded<   dS )	_TopologyTypeintSingleReplicaSetNoPrimaryReplicaSetWithPrimaryShardedUnknownLoadBalancedN)__name__
__module____qualname____annotations__     `/var/www/app.qaans.com/backend/venv/lib/python3.11/site-packages/pymongo/topology_description.pyr   r   *   sQ         KKKLLLLLLr(   r      ztuple[int, int]SRV_POLLING_TOPOLOGIESc                     e Zd Zd5dZd6dZd6dZd7dZd8dZd9dZ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e
d@d!            Ze
dAd"            Ze
d@d#            Ze
d>d$            Ze
d;d%            Ze
d;d&            ZdBd)Z	 	 dCdDd/Zej        fdEd2ZdAd3Zd<d4Zd*S )FTopologyDescriptiontopology_typer   server_descriptions!dict[_Address, ServerDescription]replica_set_nameOptional[str]max_set_versionOptional[int]max_election_idOptional[ObjectId]topology_settingsr   returnNonec                ^   || _         || _        || _        || _        || _        || _        d| _        | j         t          j        k    r| 	                                 | j
        }|s	d| _        dS t          d |D                       r	d| _        dS t          d |D                       | _        dS )a  Representation of a deployment of MongoDB servers.

        :Parameters:
          - `topology_type`: initial type
          - `server_descriptions`: dict of (address, ServerDescription) for
            all seeds
          - `replica_set_name`: replica set name or None
          - `max_set_version`: greatest setVersion seen from a primary, or None
          - `max_election_id`: greatest electionId seen from a primary, or None
          - `topology_settings`: a TopologySettings
        Nc              3  (   K   | ]}|j         d u V  d S Nlogical_session_timeout_minutes.0ss     r)   	<genexpr>z/TopologyDescription.__init__.<locals>.<genexpr>i   s*      UUq2d:UUUUUUr(   c              3  $   K   | ]}|j         V  d S r<   r=   r?   s     r)   rB   z/TopologyDescription.__init__.<locals>.<genexpr>l   s6       + +671+ + + + + +r(   )_topology_type_replica_set_name_server_descriptions_max_set_version_max_election_id_topology_settings_incompatible_errTOPOLOGY_TYPEr"   _init_incompatible_errreadable_servers_ls_timeout_minutesanymin)selfr.   r/   r1   r3   r5   r7   rM   s           r)   __init__zTopologyDescription.__init__=   s    ( ,!1$7! / / #4 "&-"<<<'')))  0 	'+D$$$UUDTUUUUU 	'+D$$$'* + +;K+ + + ( (D$$$r(   c                   | j                                         D ]}|j        s
|j        duo|j        t          j        k    }|j        duo|j        t          j        k     }|r6d|j        d         |j        d         pd|j        t          j        fz  | _	        ~|rCd|j        d         |j        d         pd|j        t          j        t          j
        fz  | _	         dS dS )z>Internal compatibility check for non-load balanced topologies.Nz]Server at %s:%d requires wire version %d, but this version of PyMongo only supports up to %d.r      zgServer at %s:%d reports wire version %d, but this version of PyMongo requires at least %d (MongoDB %s).)rF   valuesis_server_type_knownmin_wire_versionr   MAX_SUPPORTED_WIRE_VERSIONmax_wire_versionMIN_SUPPORTED_WIRE_VERSIONaddressrJ   MIN_SUPPORTED_SERVER_VERSION)rQ   rA   server_too_newserver_too_olds       r)   rL   z*TopologyDescription._init_incompatible_errp   s)   *1133 +	 +	A)  "$. K&)JJ  "$. K&)JJ   A 	!	!)*9	 &&   L 	!	!)*9; & =+	 +	r(   c                <    | j         rt          | j                   dS )zRaise ConfigurationError if any server is incompatible.

        A server is incompatible if its wire protocol version range does not
        overlap with PyMongo's.
        N)rJ   r   rQ   s    r)   check_compatiblez$TopologyDescription.check_compatible   s*     ! 	=$T%;<<<	= 	=r(   r[   r   boolc                    || j         v S r<   )rF   )rQ   r[   s     r)   
has_serverzTopologyDescription.has_server   s    $333r(   c                `    | j         |                                         }t          | |          S )z;A copy of this description, with one server marked Unknown.)rF   
to_unknownupdated_topology_description)rQ   r[   
unknown_sds      r)   reset_serverz TopologyDescription.reset_server   s+    .w7BBDD
+D*===r(   c                    | j         t          j        k    rt          j        }n| j         }d | j        D             }t          ||| j        | j        | j        | j	                  S )z<A copy of this description, with all servers marked Unknown.c                .    i | ]}|t          |          S r'   r   )r@   r[   s     r)   
<dictcomp>z-TopologyDescription.reset.<locals>.<dictcomp>   s#    \\\ww)'22\\\r(   )
rD   rK   r   r   rF   r-   rE   rG   rH   rI   )rQ   r.   sdss      r)   resetzTopologyDescription.reset   sn    -"EEE)=MM /M ]\$B[\\\""!!#
 
 	
r(   c                4    | j                                         S )z[dict of (address,
        :class:`~pymongo.server_description.ServerDescription`).
        )rF   copyr`   s    r)   r/   z'TopologyDescription.server_descriptions   s     (--///r(   c                    | j         S )zThe type of this topology.)rD   r`   s    r)   r.   z!TopologyDescription.topology_type   s     ""r(   strc                0    t           j        | j                 S )zUThe topology type as a human readable string.

        .. versionadded:: 3.4
        )rK   _fieldsrD   r`   s    r)   topology_type_namez&TopologyDescription.topology_type_name   s     $T%899r(   c                    | j         S )zThe replica set name.)rE   r`   s    r)   r1   z$TopologyDescription.replica_set_name   s     %%r(   c                    | j         S )z1Greatest setVersion seen from a primary, or None.)rG   r`   s    r)   r3   z#TopologyDescription.max_set_version        $$r(   c                    | j         S )z1Greatest electionId seen from a primary, or None.)rH   r`   s    r)   r5   z#TopologyDescription.max_election_id   rx   r(   c                    | j         S )z)Minimum logical session timeout, or None.)rN   r`   s    r)   r>   z3TopologyDescription.logical_session_timeout_minutes   s     ''r(   list[ServerDescription]c                H    d | j                                         D             S )z)List of Servers of types besides Unknown.c                     g | ]}|j         	|S r'   rV   r?   s     r)   
<listcomp>z5TopologyDescription.known_servers.<locals>.<listcomp>   s     XXXaAWXXXXr(   rF   rU   r`   s    r)   known_serversz!TopologyDescription.known_servers   s(     YX44;;==XXXXr(   c                b    t          d | j                                        D                       S )z7Whether there are any Servers of types besides Unknown.c              3  (   K   | ]}|j         	|V  d S r<   r~   r?   s     r)   rB   z8TopologyDescription.has_known_servers.<locals>.<genexpr>   s*      [[ADZ[1[[[[[[r(   )rO   rF   rU   r`   s    r)   has_known_serversz%TopologyDescription.has_known_servers   s0     [[d7>>@@[[[[[[r(   c                H    d | j                                         D             S )zList of readable Servers.c                     g | ]}|j         	|S r'   )is_readabler?   s     r)   r   z8TopologyDescription.readable_servers.<locals>.<listcomp>   s    OOOaOOOOr(   r   r`   s    r)   rM   z$TopologyDescription.readable_servers   s(     PO44;;==OOOOr(   c                T    | j         }|rt          d | j         D                       S dS )z3Minimum of all servers' max wire versions, or None.c              3  $   K   | ]}|j         V  d S r<   )rY   r?   s     r)   rB   z:TopologyDescription.common_wire_version.<locals>.<genexpr>   s%      FFaq)FFFFFFr(   N)r   rP   rQ   serverss     r)   common_wire_versionz'TopologyDescription.common_wire_version   s:     $ 	GFF43EFFFFFFtr(   c                    | j         j        S r<   )rI   heartbeat_frequencyr`   s    r)   r   z'TopologyDescription.heartbeat_frequency  s    &::r(   c                    | j         j        S r<   )rI   _srv_max_hostsr`   s    r)   srv_max_hostsz!TopologyDescription.srv_max_hosts  s    &55r(   	selectionOptional[Selection]c                    |sg S t          d |j        D                       | j        j        dz  fd|j        D             S )Nc              3  J   K   | ]}t          t          |j                  V  d S r<   r   floatround_trip_timer?   s     r)   rB   z=TopologyDescription._apply_local_threshold.<locals>.<genexpr>  s/      \\d5!"344\\\\\\r(   g     @@c                V    g | ]%}t          t          |j                  z
  k    #|&S r'   r   )r@   rA   fastest	thresholds     r)   r   z>TopologyDescription._apply_local_threshold.<locals>.<listcomp>  s@     
 
 
UA-..8YFF FFFr(   )rP   r/   rI   local_threshold_ms)rQ   r   r   r   s     @@r)   _apply_local_thresholdz*TopologyDescription._apply_local_threshold
  ss     	I\\i>[\\\\\+>G	
 
 
 
 
2
 
 
 	
r(   NselectorOptional[_Address]custom_selectorOptional[_ServerSelector]c                   t          |dd          r.| j        }|r%||j        k     rt          d||j        |fz            t	          |t
                    r|                    |            | j        t          j	        k    rg S | j        t          j
        t          j        fv r| j        S |r.|                                                     |          }|r|gng S t          j        |           }| j        t          j        k    r ||          }|%|r#|                     ||j                            }|                     |          S )a  List of servers matching the provided selector(s).

        :Parameters:
          - `selector`: a callable that takes a Selection as input and returns
            a Selection as output. For example, an instance of a read
            preference from :mod:`~pymongo.read_preferences`.
          - `address` (optional): A server address to select.
          - `custom_selector` (optional): A callable that augments server
            selection rules. Accepts a list of
            :class:`~pymongo.server_description.ServerDescription` objects and
            return a list of server descriptions that should be considered
            suitable for the desired operation.

        .. versionadded:: 3.4
        rW   r   zF%s requires min wire version %d, but topology's min wire version is %d)getattrr   rW   r   
isinstancer   selection_hookr.   rK   r!   r   r"   r   r/   getr   from_topology_descriptionr    with_server_descriptionsr   )rQ   r   r[   r   	common_wvdescriptionr   s          r)   apply_selectorz"TopologyDescription.apply_selector  sq   * 8/33 	0I Y)BBB(*-5x7PR[,\]  
 h.. 	*##D)))!666IM$8-:T#UUU%% 	8224488AAK$/7K==R77==	!666 ++I &9&!::	 =>> I **9555r(   read_preferencer   c                p    t          j        d|           t          |                     |                    S )a  Does this topology have any readable servers available matching the
        given read preference?

        :Parameters:
          - `read_preference`: an instance of a read preference from
            :mod:`~pymongo.read_preferences`. Defaults to
            :attr:`~pymongo.read_preferences.ReadPreference.PRIMARY`.

        .. note:: When connected directly to a single server this method
          always returns ``True``.

        .. versionadded:: 3.4
        r   )r   validate_read_preferencerO   r   )rQ   r   s     r)   has_readable_serverz'TopologyDescription.has_readable_serverL  s4     	'(9?KKK4&&77888r(   c                @    |                      t          j                  S )zDoes this topology have a writable server available?

        .. note:: When connected directly to a single server this method
          always returns ``True``.

        .. versionadded:: 3.4
        )r   r   PRIMARYr`   s    r)   has_writable_serverz'TopologyDescription.has_writable_server]  s     ''(>???r(   c                    t          | j                                        d           }d                    | j        j        | j        j        | j        |          S )Nc                    | j         S r<   )r[   )sds    r)   <lambda>z.TopologyDescription.__repr__.<locals>.<lambda>i  s    BJ r(   )keyz-<{} id: {}, topology_type: {}, servers: {!r}>)	sortedrF   rU   format	__class__r#   rI   _topology_idru   r   s     r)   __repr__zTopologyDescription.__repr__g  sY    299;;AVAVWWW>EEN##0#	
 
 	
r(   )r.   r   r/   r0   r1   r2   r3   r4   r5   r6   r7   r   r8   r9   )r8   r9   )r[   r   r8   rb   )r[   r   r8   r-   )r8   r-   )r8   r0   )r8   r   )r8   rr   )r8   r2   )r8   r4   )r8   r6   )r8   r{   )r8   rb   )r   r   r8   r{   )NN)r   r   r[   r   r   r   r8   r{   )r   r   r8   rb   )r#   r$   r%   rR   rL   ra   rd   ri   rn   r/   propertyr.   ru   r1   r3   r5   r>   r   r   rM   r   r   r   r   r   r   r   r   r   r   r'   r(   r)   r-   r-   <   s       1 1 1 1f- - - -^= = = =4 4 4 4> > > >

 
 
 
&0 0 0 0 # # # X# : : : X: & & & X& % % % X% % % % X% ( ( ( X( Y Y Y XY \ \ \ X\ P P P XP    X ; ; ; X; 6 6 6 X6

 

 

 

 '+59	46 46 46 46 46l BPAW 9 9 9 9 9"@ @ @ @
 
 
 
 
 
r(   r-   topology_descriptionserver_descriptionr   r8   c                $   |j         }| j        }| j        }| j        }| j        }|j        }|                                 }|||<   |t          j        k    rq|L||j        k    rAt          d
                    ||j                            }	|                    |	          ||<   t          t          j        ||||| j                  S |t          j        k    r|t          j        t          j        fv r@t%          | j        j                  dk    rt          j        }n=|                    |           n'|t          j        t          j        fvrt,          |         }|t          j        k    r1|t          j        t          j        fvr|                    |           nb|t          j        k    r|t          j        t          j        fv r|                    |           n!|t          j        k    rt7          |||||          \  }}}}n|t          j        t          j        t          j        fv rt?          |||          \  }}n|t          j         k    r|t          j        t          j        fv r%|                    |           tC          |          }no|t          j        k    rt7          |||||          \  }}}}nF|t          j        t          j        t          j        fv rtE          |||          }ntC          |          }t          |||||| j                  S )a}  Return an updated copy of a TopologyDescription.

    :Parameters:
      - `topology_description`: the current TopologyDescription
      - `server_description`: a new ServerDescription that resulted from
        a hello call

    Called after attempting (successfully or not) to call hello on the
    server at server_description.address. Does not modify topology_description.
    Nzeclient is configured to connect to a replica set named '{}' but this node belongs to a set named '{}')errorrT   )#r[   r.   r1   r3   r5   server_typer/   rK   r   r   r   rf   r-   rI   r!   r   
StandaloneLoadBalancerlenseedspopRSGhost_SERVER_TYPE_TO_TOPOLOGY_TYPEr    Mongosr   	RSPrimary_update_rs_from_primaryRSSecondary	RSArbiterRSOther!_update_rs_no_primary_from_memberr   _check_has_primary#_update_rs_with_primary_from_member)
r   r   r[   r.   set_namer3   r5   r   rm   r   s
             r)   rg   rg   ~  s2    !(G )6M#4H*:O*:O$0K 
2
2
4
4C &CL,,,H0B0S$S$S&AAG0AB B E .88u8EECL"  3
 
 	
 ---;1;3KLLL':@AAQFF - 4     !4k6I JJJ9+FM---{1;3FGGGGGG	-;	;	;;1;3EFFFGGGK111JaX1?OK KG]Ho [4k6K[M`aaa&GX1' '#M8 
-=	=	=;1;3EFFFGGG.s33MMK111JaX1?OK KG]Ho [4k6K[M`aaa?XOabbMM /s33M /  r(   seedlistlist[tuple[str, Any]]c           	        | j         t          v sJ |                                 }t          |                                          t          |          k    r| S t          |                                          D ]}||vr|                    |           | j        dk    rt          |          t          |                                          z
  }| j        t          |          z
  }|dk    r9t          t          |          t          |t          |                              }ng }|D ]}||vrt          |          ||<   t          | j         || j        | j        | j        | j                  S )zReturn an updated copy of a TopologyDescription.

    :Parameters:
      - `topology_description`: the current TopologyDescription
      - `seedlist`: a list of new seeds new ServerDescription that resulted from
        a hello call
    r   )r.   r+   r/   setkeyslistr   r   r   r   r   rP   r   r-   r1   r3   r5   rI   )r   r   rm   r[   	new_hostsn_to_adds         r)   )_updated_topology_description_srv_pollingr     se     -1GGGGG

2
2
4
4C 388::#h--''## 

##  (""GGG)Q..MMC

OO3	'5C@a<<fY//Xs9~~1N1NOOHHH 6 6#,W55CL*-,,/  r(   rm   +MutableMapping[_Address, ServerDescription]r1   r2   r3   r4   r5   r6   <tuple[int, Optional[str], Optional[int], Optional[ObjectId]]c                   ||j         }n8||j         k    r-|                     |j                   t          |           |||fS |j        |j        dk     rr|j        |j        f}||f}d|vr@d|vr5||k     r/|                                | |j        <   t          |           |||fS |j        }|j        ||j        |k    r|j        }n|j        |j        f}||f}t          d |D                       }t          d |D                       }||k     r/|                                | |j        <   t          |           |||fS |j        }|j        }| 	                                D ]C}	|	j
        t          j        u r.|	j        |j        k    r|	                                | |	j        <    nD|j        D ]}
|
| vrt          |
          | |
<   t          |           |j        z
  D ]}|                     |           t          |           |||fS )ag  Update topology description from a primary's hello response.

    Pass in a dict of ServerDescriptions, current replica set name, the
    ServerDescription we are processing, and the TopologyDescription's
    max_set_version and max_election_id if any.

    Returns (new topology type, new replica_set_name, new max_set_version,
    new max_election_id).
    N   c              3  :   K   | ]}|t                      n|V  d S r<   r   r@   is     r)   rB   z*_update_rs_from_primary.<locals>.<genexpr>=  .      ![![1ai&(((Q![![![![![![r(   c              3  :   K   | ]}|t                      n|V  d S r<   r   r   s     r)   rB   z*_update_rs_from_primary.<locals>.<genexpr>>  r   r(   )r1   r   r[   r   rY   set_versionelection_idrf   tuplerU   r   r   r   	all_hostsr   r   )rm   r1   r   r3   r5   new_election_tuplemax_election_tuplenew_election_safemax_election_safeservernew_addressaddrs               r)   r   r     s     ->	/@	@	@ 	"*+++!#&&(8/?ZZ*26H6Y\^6^6^%7%CEWEc$d%4o$F)))---2DGY2Y2Y2D2O2O2Q2Q&./)#..0@/Sbbb0<O)5#'9'E'W'W0<O/;=O=[[,o=!![![HZ![![![[[!![![HZ![![![[[000.@.K.K.M.MC"*+%c**,<o^^0<O0<O **,, 
 
+"777"4"<<< #)"3"3"5"5C E *3 > >c!!0==C C-77   s##%5XXr(   r   c                    |J ||j         k    r|                     |j                   n1|j        r*|j        |j        k    r|                     |j                   t	          |           S )zRS with known primary. Process a response from a non-primary.

    Pass in a dict of ServerDescriptions, current replica set name, and the
    ServerDescription we are processing.

    Returns new topology type.
    )r1   r   r[   mer   )rm   r1   r   s      r)   r   r   b  s{     '''->>>"*++++		 ,#5#=ASAV#V#V"*+++ c"""r(   tuple[int, Optional[str]]c                *   t           j        }||j        }n)||j        k    r|                     |j                   ||fS |j        D ]}|| vrt          |          | |<   |j        r*|j        |j        k    r|                     |j                   ||fS )zRS without known primary. Update from a non-primary's response.

    Pass in a dict of ServerDescriptions, current replica set name, and the
    ServerDescription we are processing.

    Returns (new topology type, new replica_set_name).
    )rK   r   r1   r   r[   r   r   r   )rm   r1   r   r.   r[   s        r)   r   r   y  s     "5M->	/@	@	@"*+++... &/ 6 6#,W55CL ,!3!;?Q?T!T!T"*+++***r(   $Mapping[_Address, ServerDescription]c                    |                                  D ]%}|j        t          j        k    rt          j        c S &t          j        S )zCurrent topology type is ReplicaSetWithPrimary. Is primary still known?

    Pass in a dict of ServerDescriptions.

    Returns new topology type.
    )rU   r   r   r   rK   r   r   )rm   rA   s     r)   r   r     sJ     ZZ\\ 1 1=K111 6666 2 00r(   N)r   r-   r   r   r8   r-   )r   r-   r   r   r8   r-   )rm   r   r1   r2   r   r   r3   r4   r5   r6   r8   r   )rm   r   r1   r2   r   r   r8   r   )rm   r   r1   r2   r   r   r8   r   )rm   r   r8   r   )9__doc__
__future__r   randomr   typingr   r   r   r   r	   r
   r   r   bson.min_keyr   bson.objectidr   pymongor   pymongo.errorsr   pymongo.read_preferencesr   r   r   pymongo.server_descriptionr   pymongo.server_selectorsr   pymongo.server_typer   pymongo.typingsr   r   rangerK   r!   r    r+   r&   _ServerSelectorr-   r   r   r   r   r   r   r   r   rg   r   r   r   r   r   r'   r(   r)   <module>r     s   1 0 0 " " " " " "      	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	        " " " " " "       - - - - - - O O O O O O O O O O 8 8 8 8 8 8 . . . . . . + + + + + + $ $ $ $ $ $    J    uuQxx( ,9+@-BW*X  X X X X D!234d;L6MMNs
 s
 s
 s
 s
 s
 s
 s
r	 -=>]>=<:! f f f fR) ) ) )XLY LY LY LY^# # # #.+ + + +@1 1 1 1 1 1r(   