@@ -132,11 +132,11 @@ cdef class ConnectParamsImpl:
132
132
self ._default_description = Description()
133
133
self ._default_address = Address()
134
134
self .description_list = DescriptionList()
135
- self .description_list.descriptions .append(self ._default_description)
135
+ self .description_list.children .append(self ._default_description)
136
136
self .debug_jdwp = os.getenv(" ORA_DEBUG_JDWP" )
137
137
address_list = AddressList()
138
- address_list.addresses .append(self ._default_address)
139
- self ._default_description.address_lists .append(address_list)
138
+ address_list.children .append(self ._default_address)
139
+ self ._default_description.children .append(address_list)
140
140
141
141
def set (self , dict args ):
142
142
"""
@@ -369,10 +369,10 @@ cdef class ConnectParamsImpl:
369
369
description.set_from_connect_data_args(args)
370
370
description.set_from_description_args(args)
371
371
description.set_from_security_args(args)
372
- description.address_lists = [AddressList()]
373
- description.address_lists [0 ].addresses .append(address)
372
+ description.children = [AddressList()]
373
+ description.children [0 ].children .append(address)
374
374
self .description_list = DescriptionList()
375
- self .description_list.descriptions .append(description)
375
+ self .description_list.children .append(description)
376
376
377
377
# otherwise, see if the name is a connect alias in a tnsnames.ora
378
378
# configuration file
@@ -405,7 +405,7 @@ cdef class ConnectParamsImpl:
405
405
for desc_args in list_args.get(" description" , [list_args]):
406
406
description = self ._default_description.copy()
407
407
description.set_from_description_args(desc_args)
408
- self .description_list.descriptions .append(description)
408
+ self .description_list.children .append(description)
409
409
sub_args = desc_args.get(" connect_data" )
410
410
if sub_args is not None :
411
411
description.set_from_connect_data_args(sub_args)
@@ -415,11 +415,11 @@ cdef class ConnectParamsImpl:
415
415
for list_args in desc_args.get(" address_list" , [desc_args]):
416
416
address_list = AddressList()
417
417
address_list.set_from_args(list_args)
418
- description.address_lists .append(address_list)
418
+ description.children .append(address_list)
419
419
for addr_args in list_args.get(" address" , []):
420
420
address = self ._default_address.copy()
421
421
address.set_from_args(addr_args)
422
- address_list.addresses .append(address)
422
+ address_list.children .append(address)
423
423
424
424
cdef int _set_access_token(self , object val, int error_num) except - 1 :
425
425
"""
@@ -521,9 +521,9 @@ cdef class ConnectParamsImpl:
521
521
AddressList addr_list
522
522
Description desc
523
523
Address addr
524
- return [addr for desc in self .description_list.descriptions \
525
- for addr_list in desc.address_lists \
526
- for addr in addr_list.addresses ]
524
+ return [addr for desc in self .description_list.children \
525
+ for addr_list in desc.children \
526
+ for addr in addr_list.children ]
527
527
528
528
def get_connect_string (self ):
529
529
"""
@@ -618,13 +618,74 @@ cdef class ConnectParamsImpl:
618
618
return dsn
619
619
620
620
621
- cdef class Address:
621
+ cdef class ConnectParamsNode:
622
+
623
+ def __init__ (self , bint must_have_children ):
624
+ self .must_have_children = must_have_children
625
+ self .failover = True
626
+ if must_have_children:
627
+ self .children = []
628
+
629
+ cdef int _copy(self , ConnectParamsNode source) except - 1 :
630
+ """
631
+ Copies data from the source to this node.
632
+ """
633
+ self .must_have_children = source.must_have_children
634
+ if self .must_have_children:
635
+ self .children = []
636
+ self .failover = source.failover
637
+ self .load_balance = source.load_balance
638
+ self .source_route = source.source_route
639
+
640
+ cdef int _set_active_children(self ) except - 1 :
641
+ """
642
+ Set the active children to process when connecting to the database.
643
+ This call is recursive and will set the active children of each of its
644
+ children.
645
+ """
646
+ cdef ConnectParamsNode child
647
+
648
+ # if only one child is present, that child is considered active
649
+ if len (self .children) == 1 :
650
+ self .active_children = self .children
651
+
652
+ # for source route, only the first child is considered active
653
+ elif self .source_route:
654
+ self .active_children = self .children[:1 ]
655
+
656
+ # for failover with load balance, all of the children are active but
657
+ # are processed in a random order
658
+ elif self .failover and self .load_balance:
659
+ self .active_children = random.sample(self .children,
660
+ k = len (self .children))
661
+
662
+ # for failover without load balance, all of the children are active and
663
+ # are processed in the same order
664
+ elif self .failover:
665
+ self .active_children = self .children
666
+
667
+ # without failover, load balance indicates that only one of the
668
+ # children is considered active and which one is selected randomly
669
+ elif self .load_balance:
670
+ self .active_children = random.sample(self .children, k = 1 )
671
+
672
+ # without failover or load balance, just the first child is navigated
673
+ else :
674
+ self .active_children = self .children[:1 ]
675
+
676
+ for child in self .children:
677
+ if child.must_have_children:
678
+ child._set_active_children()
679
+
680
+
681
+ cdef class Address(ConnectParamsNode):
622
682
"""
623
683
Internal class used to hold parameters for an address used to create a
624
684
connection to the database.
625
685
"""
626
686
627
687
def __init__ (self ):
688
+ ConnectParamsNode.__init__ (self , False )
628
689
self .protocol = DEFAULT_PROTOCOL
629
690
self .port = DEFAULT_PORT
630
691
@@ -648,6 +709,7 @@ cdef class Address:
648
709
Creates a copy of the address and returns it.
649
710
"""
650
711
cdef Address address = Address.__new__ (Address)
712
+ address._copy(self )
651
713
address.host = self .host
652
714
address.port = self .port
653
715
address.protocol = self .protocol
@@ -677,22 +739,22 @@ cdef class Address:
677
739
_set_uint_param(args, " https_proxy_port" , & self .https_proxy_port)
678
740
679
741
680
- cdef class AddressList:
742
+ cdef class AddressList(ConnectParamsNode) :
681
743
"""
682
744
Internal class used to hold address list parameters and a list of addresses
683
745
used to create connections to the database.
684
746
"""
685
747
686
748
def __init__ (self ):
687
- self .addresses = []
749
+ ConnectParamsNode. __init__ ( self , True )
688
750
689
751
cdef bint _uses_tcps(self ):
690
752
"""
691
753
Returns a boolean indicating if any of the addresses in the address
692
754
list use the protocol TCPS.
693
755
"""
694
756
cdef Address address
695
- for address in self .addresses :
757
+ for address in self .children :
696
758
if address.protocol == " tcps" :
697
759
return True
698
760
return False
@@ -702,7 +764,7 @@ cdef class AddressList:
702
764
Build a connect string from the components.
703
765
"""
704
766
cdef Address a
705
- parts = [a.build_connect_string() for a in self .addresses ]
767
+ parts = [a.build_connect_string() for a in self .children ]
706
768
if len (parts) == 1 :
707
769
return parts[0 ]
708
770
return f' (ADDRESS_LIST={"".join(parts)})'
@@ -712,17 +774,18 @@ cdef class AddressList:
712
774
Set paramter values from an argument dictionary or an (ADDRESS_LIST)
713
775
node in a connect descriptor.
714
776
"""
777
+ _set_bool_param(args, " failover" , & self .failover)
715
778
_set_bool_param(args, " load_balance" , & self .load_balance)
716
779
_set_bool_param(args, " source_route" , & self .source_route)
717
780
718
781
719
- cdef class Description:
782
+ cdef class Description(ConnectParamsNode) :
720
783
"""
721
784
Internal class used to hold description parameters.
722
785
"""
723
786
724
787
def __init__ (self ):
725
- self .address_lists = []
788
+ ConnectParamsNode. __init__ ( self , True )
726
789
self .tcp_connect_timeout = DEFAULT_TCP_CONNECT_TIMEOUT
727
790
self .ssl_server_dn_match = True
728
791
@@ -769,7 +832,7 @@ cdef class Description:
769
832
# add address lists, but if the address list contains only a single
770
833
# entry and that entry does not have a host, the other parts aren't
771
834
# relevant anyway!
772
- for address_list in self .address_lists :
835
+ for address_list in self .children :
773
836
temp = address_list.build_connect_string()
774
837
if temp is None :
775
838
return None
@@ -818,7 +881,7 @@ cdef class Description:
818
881
returns it.
819
882
"""
820
883
cdef Description description = Description.__new__ (Description)
821
- description.address_lists = []
884
+ description._copy( self )
822
885
description.service_name = self .service_name
823
886
description.sid = self .sid
824
887
description.server_type = self .server_type
@@ -855,6 +918,7 @@ cdef class Description:
855
918
"""
856
919
cdef Address address
857
920
_set_uint_param(args, " expire_time" , & self .expire_time)
921
+ _set_bool_param(args, " failover" , & self .failover)
858
922
_set_bool_param(args, " load_balance" , & self .load_balance)
859
923
_set_bool_param(args, " source_route" , & self .source_route)
860
924
_set_uint_param(args, " retry_count" , & self .retry_count)
@@ -872,14 +936,14 @@ cdef class Description:
872
936
_set_str_param(args, " wallet_location" , self )
873
937
874
938
875
- cdef class DescriptionList:
939
+ cdef class DescriptionList(ConnectParamsNode) :
876
940
"""
877
941
Internal class used to hold description list parameters and a list of
878
942
descriptions.
879
943
"""
880
944
881
945
def __init__ (self ):
882
- self .descriptions = []
946
+ ConnectParamsNode. __init__ ( self , True )
883
947
884
948
cdef str build_connect_string(self ):
885
949
"""
@@ -888,7 +952,7 @@ cdef class DescriptionList:
888
952
cdef:
889
953
Description d
890
954
list parts
891
- parts = [d.build_connect_string() for d in self .descriptions ]
955
+ parts = [d.build_connect_string() for d in self .children ]
892
956
if len (parts) == 1 :
893
957
return parts[0 ]
894
958
return f' (DESCIPTION_LIST={"".join(parts)})'
@@ -898,6 +962,7 @@ cdef class DescriptionList:
898
962
Set paramter values from an argument dictionary or a (DESCRIPTION_LIST)
899
963
node in a connect descriptor.
900
964
"""
965
+ _set_bool_param(args, " failover" , & self .failover)
901
966
_set_bool_param(args, " load_balance" , & self .load_balance)
902
967
_set_bool_param(args, " source_route" , & self .source_route)
903
968
0 commit comments