16
16
17
17
import base64
18
18
from collections import OrderedDict
19
+ import copy
19
20
import datetime
20
21
21
22
from google .cloud ._helpers import UTC
@@ -468,6 +469,31 @@ def to_api_repr(self):
468
469
resource ['name' ] = self .name
469
470
return resource
470
471
472
+ def _key (self ):
473
+ """A tuple key that uniquely describes this field.
474
+
475
+ Used to compute this instance's hashcode and evaluate equality.
476
+
477
+ Returns:
478
+ tuple: The contents of this :class:`ScalarQueryParameter`.
479
+ """
480
+ return (
481
+ self .name ,
482
+ self .type_ .upper (),
483
+ self .value ,
484
+ )
485
+
486
+ def __eq__ (self , other ):
487
+ if not isinstance (other , ScalarQueryParameter ):
488
+ return NotImplemented
489
+ return self ._key () == other ._key ()
490
+
491
+ def __ne__ (self , other ):
492
+ return not self == other
493
+
494
+ def __repr__ (self ):
495
+ return 'ScalarQueryParameter{}' .format (self ._key ())
496
+
471
497
472
498
class ArrayQueryParameter (AbstractQueryParameter ):
473
499
"""Named / positional query parameters for array values.
@@ -507,15 +533,24 @@ def positional(cls, array_type, values):
507
533
return cls (None , array_type , values )
508
534
509
535
@classmethod
510
- def from_api_repr (cls , resource ):
511
- """Factory: construct parameter from JSON resource.
512
-
513
- :type resource: dict
514
- :param resource: JSON mapping of parameter
536
+ def _from_api_repr_struct (cls , resource ):
537
+ name = resource .get ('name' )
538
+ converted = []
539
+ # We need to flatten the array to use the StructQueryParameter
540
+ # parse code.
541
+ resource_template = {
542
+ # The arrayType includes all the types of the fields of the STRUCT
543
+ 'parameterType' : resource ['parameterType' ]['arrayType' ]
544
+ }
545
+ for array_value in resource ['parameterValue' ]['arrayValues' ]:
546
+ struct_resource = copy .deepcopy (resource_template )
547
+ struct_resource ['parameterValue' ] = array_value
548
+ struct_value = StructQueryParameter .from_api_repr (struct_resource )
549
+ converted .append (struct_value )
550
+ return cls (name , 'STRUCT' , converted )
515
551
516
- :rtype: :class:`ArrayQueryParameter`
517
- :returns: instance
518
- """
552
+ @classmethod
553
+ def _from_api_repr_scalar (cls , resource ):
519
554
name = resource .get ('name' )
520
555
array_type = resource ['parameterType' ]['arrayType' ]['type' ]
521
556
values = [
@@ -526,14 +561,29 @@ def from_api_repr(cls, resource):
526
561
_CELLDATA_FROM_JSON [array_type ](value , None ) for value in values ]
527
562
return cls (name , array_type , converted )
528
563
564
+ @classmethod
565
+ def from_api_repr (cls , resource ):
566
+ """Factory: construct parameter from JSON resource.
567
+
568
+ :type resource: dict
569
+ :param resource: JSON mapping of parameter
570
+
571
+ :rtype: :class:`ArrayQueryParameter`
572
+ :returns: instance
573
+ """
574
+ array_type = resource ['parameterType' ]['arrayType' ]['type' ]
575
+ if array_type == 'STRUCT' :
576
+ return cls ._from_api_repr_struct (resource )
577
+ return cls ._from_api_repr_scalar (resource )
578
+
529
579
def to_api_repr (self ):
530
580
"""Construct JSON API representation for the parameter.
531
581
532
582
:rtype: dict
533
583
:returns: JSON mapping
534
584
"""
535
585
values = self .values
536
- if self .array_type == 'RECORD' :
586
+ if self .array_type == 'RECORD' or self . array_type == 'STRUCT' :
537
587
reprs = [value .to_api_repr () for value in values ]
538
588
a_type = reprs [0 ]['parameterType' ]
539
589
a_values = [repr_ ['parameterValue' ] for repr_ in reprs ]
@@ -556,6 +606,31 @@ def to_api_repr(self):
556
606
resource ['name' ] = self .name
557
607
return resource
558
608
609
+ def _key (self ):
610
+ """A tuple key that uniquely describes this field.
611
+
612
+ Used to compute this instance's hashcode and evaluate equality.
613
+
614
+ Returns:
615
+ tuple: The contents of this :class:`ArrayQueryParameter`.
616
+ """
617
+ return (
618
+ self .name ,
619
+ self .array_type .upper (),
620
+ self .values ,
621
+ )
622
+
623
+ def __eq__ (self , other ):
624
+ if not isinstance (other , ArrayQueryParameter ):
625
+ return NotImplemented
626
+ return self ._key () == other ._key ()
627
+
628
+ def __ne__ (self , other ):
629
+ return not self == other
630
+
631
+ def __repr__ (self ):
632
+ return 'ArrayQueryParameter{}' .format (self ._key ())
633
+
559
634
560
635
class StructQueryParameter (AbstractQueryParameter ):
561
636
"""Named / positional query parameters for struct values.
@@ -606,14 +681,32 @@ def from_api_repr(cls, resource):
606
681
"""
607
682
name = resource .get ('name' )
608
683
instance = cls (name )
684
+ type_resources = {}
609
685
types = instance .struct_types
610
686
for item in resource ['parameterType' ]['structTypes' ]:
611
687
types [item ['name' ]] = item ['type' ]['type' ]
688
+ type_resources [item ['name' ]] = item ['type' ]
612
689
struct_values = resource ['parameterValue' ]['structValues' ]
613
690
for key , value in struct_values .items ():
614
691
type_ = types [key ]
615
- value = value ['value' ]
616
- converted = _CELLDATA_FROM_JSON [type_ ](value , None )
692
+ converted = None
693
+ if type_ == 'STRUCT' :
694
+ struct_resource = {
695
+ 'name' : key ,
696
+ 'parameterType' : type_resources [key ],
697
+ 'parameterValue' : value ,
698
+ }
699
+ converted = StructQueryParameter .from_api_repr (struct_resource )
700
+ elif type_ == 'ARRAY' :
701
+ struct_resource = {
702
+ 'name' : key ,
703
+ 'parameterType' : type_resources [key ],
704
+ 'parameterValue' : value ,
705
+ }
706
+ converted = ArrayQueryParameter .from_api_repr (struct_resource )
707
+ else :
708
+ value = value ['value' ]
709
+ converted = _CELLDATA_FROM_JSON [type_ ](value , None )
617
710
instance .struct_values [key ] = converted
618
711
return instance
619
712
@@ -651,6 +744,31 @@ def to_api_repr(self):
651
744
resource ['name' ] = self .name
652
745
return resource
653
746
747
+ def _key (self ):
748
+ """A tuple key that uniquely describes this field.
749
+
750
+ Used to compute this instance's hashcode and evaluate equality.
751
+
752
+ Returns:
753
+ tuple: The contents of this :class:`ArrayQueryParameter`.
754
+ """
755
+ return (
756
+ self .name ,
757
+ self .struct_types ,
758
+ self .struct_values ,
759
+ )
760
+
761
+ def __eq__ (self , other ):
762
+ if not isinstance (other , StructQueryParameter ):
763
+ return NotImplemented
764
+ return self ._key () == other ._key ()
765
+
766
+ def __ne__ (self , other ):
767
+ return not self == other
768
+
769
+ def __repr__ (self ):
770
+ return 'StructQueryParameter{}' .format (self ._key ())
771
+
654
772
655
773
class QueryParametersProperty (object ):
656
774
"""Custom property type, holding query parameter instances."""
0 commit comments