@@ -872,10 +872,120 @@ def resolve(self, bindings, used):
872872
873873
874874class Query :
875- __slots__ = ()
875+ """Query object.
876876
877- def __init__ (self , * args , ** kwargs ):
878- raise NotImplementedError
877+ Args:
878+ kind (str): The kind of entities to be queried.
879+ ancestor (Key): Entities returned will be descendants of `ancestor`.
880+ filters (Union[Node, tuple]): Node representing a filter expression
881+ tree. Property filters applied by this query. The sequence
882+ is ``(property_name, operator, value)``.
883+ orders (Union[datastore_query.Order, list]): The field names used to
884+ order query results. Renamed `order` in google.cloud.datastore.
885+ app (str): The namespace to restrict results. If not passed, uses the
886+ client's value. Renamed `project` in google.cloud.datastore.
887+ namespace (str): The namespace to which to restrict results.
888+ If not passed, uses the client's value.
889+ default_options (QueryOptions): QueryOptions object.
890+ projection (Union[list, tuple]): The fields returned as part of the
891+ query results.
892+ group_by (Union[list, tuple]): The field names used to group query
893+ results. Renamed distinct_on in google.cloud.datastore.
894+
895+ Raises: TypeError if any of the arguments are invalid.
896+ """
897+
898+ def __init__ (self , kind = None , ancestor = None , filters = None , orders = None ,
899+ app = None , namespace = None , default_options = None ,
900+ projection = None , group_by = None ):
901+ if ancestor is not None :
902+ if isinstance (ancestor , ParameterizedThing ):
903+ if isinstance (ancestor , ParameterizedFunction ):
904+ if ancestor .func != 'key' :
905+ raise TypeError ("ancestor cannot be a GQL function"
906+ "other than Key" )
907+ else :
908+ if not isinstance (ancestor , model .Key ):
909+ raise TypeError ("ancestor must be a Key; "
910+ F"received { ancestor } " )
911+ if not ancestor .id ():
912+ raise ValueError ("ancestor cannot be an incomplete key" )
913+ if app is not None :
914+ if app != ancestor .app ():
915+ raise TypeError ("ancestor/app id mismatch" )
916+ else :
917+ app = ancestor .app ()
918+ if namespace is not None :
919+ if namespace != ancestor .namespace ():
920+ raise TypeError ("ancestor/namespace mismatch" )
921+ else :
922+ namespace = ancestor .namespace ()
923+ if filters is not None :
924+ if not isinstance (filters , Node ):
925+ raise TypeError ("filters must be a query Node or None; "
926+ F"received { filters } " )
927+ if orders is not None :
928+ if not isinstance (orders , (list ,)): # datastore_query.Order
929+ raise TypeError ("orders must be an Order instance or None; "
930+ F"received { orders } " )
931+ # if default_options is not None: # Optional QueryOptions object.
932+ # if not isinstance(default_options, datastore_rpc.BaseConfiguration):
933+ # raise TypeError("default_options must be a Configuration or None; "
934+ # F"received {default_options}")
935+ # if projection is not None:
936+ # if default_options.projection is not None:
937+ # raise TypeError("cannot use projection keyword argument and "
938+ # "default_options.projection at the same time")
939+ # if default_options.keys_only is not None:
940+ # raise TypeError("cannot use projection keyword argument and "
941+ # "default_options.keys_only at the same time")
942+
943+ self .kind = kind
944+ self .ancestor = ancestor
945+ self .filters = filters
946+ self .orders = orders
947+ self .app = app
948+ self .namespace = namespace
949+ self .default_options = default_options
950+
951+ self .projection = None
952+ if projection is not None :
953+ if not projection :
954+ raise TypeError ('projection argument cannot be empty' )
955+ if not isinstance (projection , (tuple , list )):
956+ raise TypeError ("projection must be a tuple, list or None; "
957+ F"received { projection } " )
958+ self ._check_properties (self ._to_property_names (projection ))
959+ self .projection = tuple (projection )
960+
961+ self .group_by = None
962+ if group_by is not None :
963+ if not group_by :
964+ raise TypeError ('group_by argument cannot be empty' )
965+ if not isinstance (group_by , (tuple , list )):
966+ raise TypeError ("group_by must be a tuple, list or None; "
967+ F"received { group_by } " )
968+ self ._check_properties (self ._to_property_names (group_by ))
969+ self .group_by = tuple (group_by )
970+
971+ def _to_property_names (self , properties ):
972+ if not isinstance (properties , (list , tuple )):
973+ properties = [properties ]
974+ fixed = []
975+ for prop in properties :
976+ if isinstance (prop , str ):
977+ fixed .append (prop )
978+ elif isinstance (prop , model .Property ):
979+ fixed .append (prop ._name )
980+ else :
981+ raise TypeError (
982+ F"Unexpected property { prop } ; should be string or Property" )
983+ return fixed
984+
985+ def _check_properties (self , fixed , ** kwargs ):
986+ modelclass = model .Model ._kind_map .get (self .__kind )
987+ if modelclass is not None :
988+ modelclass ._check_properties (fixed , ** kwargs )
879989
880990
881991def gql (* args , ** kwargs ):
0 commit comments