U
    b+d'                     @   s~   e  ZG d d dZG dd dZG dd dZG dd deZG dd	 d	eZG d
d dZG dd dZG dd dZ	dS )c                   @   s   e Zd ZdddZdd ZdS )Limit    c                 C   s   || _ || _d S N)offsetcount)selfr   r    r   E/tmp/pip-unpacked-wheel-cdsyf3nb/redis/commands/search/aggregation.py__init__   s    zLimit.__init__c                 C   s$   | j rdt| jt| j gS g S d S )NZLIMIT)r   strr   r   r   r   r   
build_args	   s    zLimit.build_argsN)r   r   __name__
__module____qualname__r	   r   r   r   r   r   r      s   
r   c                   @   s0   e Zd ZdZdZdd Zdd Zedd ZdS )	Reducerzr
    Base reducer object for all reducers.

    See the `redisearch.reducers` module for the actual reducers.
    Nc                 G   s   || _ d | _d | _d S r   )_args_field_aliasr   argsr   r   r   r	      s    zReducer.__init__c                 C   s.   |t kr$| jstd| jdd }|| _| S )a  
        Set the alias for this reducer.

        ### Parameters

        - **alias**: The value of the alias for this reducer. If this is the
            special value `aggregation.FIELDNAME` then this reducer will be
            aliased using the same name as the field upon which it operates.
            Note that using `FIELDNAME` is only possible on reducers which
            operate on a single field value.

        This method returns the `Reducer` object making it suitable for
        chaining.
        z(Cannot use FIELDNAME alias with no field   N)	FIELDNAMEr   
ValueErrorr   )r   aliasr   r   r   r      s    zReducer.aliasc                 C   s   | j S r   )r   r   r   r   r   r   5   s    zReducer.args)	r   r   r   __doc__NAMEr	   r   propertyr   r   r   r   r   r      s   r   c                   @   s   e Zd ZdZdZdd ZdS )SortDirectionz@
    This special class is used to indicate sort direction.
    Nc                 C   s
   || _ d S r   )field)r   r   r   r   r   r	   A   s    zSortDirection.__init__)r   r   r   r   	DIRSTRINGr	   r   r   r   r   r   :   s   r   c                   @   s   e Zd ZdZdZdS )AsczK
    Indicate that the given field should be sorted in ascending order
    ASCNr   r   r   r   r    r   r   r   r   r!   E   s   r!   c                   @   s   e Zd ZdZdZdS )DesczL
    Indicate that the given field should be sorted in descending order
    ZDESCNr#   r   r   r   r   r$   M   s   r$   c                   @   st   e Zd ZdZdddZdd Zdd Zd	d
 Zdd Zdd Z	dd Z
dd Zdd ZdddZdd Zdd ZdS ) AggregateRequestzH
    Aggregation request which can be passed to `Client.aggregate`.
    *c                 C   s:   || _ g | _g | _d| _d| _d| _d| _g | _d| _dS )a}  
        Create an aggregation request. This request may then be passed to
        `client.aggregate()`.

        In order for the request to be usable, it must contain at least one
        group.

        - **query** Query string for filtering records.

        All member methods (except `build_args()`)
        return the object itself, making them useful for chaining.
        Fr   N)	_query_aggregateplan_loadfields_loadallZ_max_with_schema	_verbatim_cursor_dialect)r   queryr   r   r   r	   Z   s    zAggregateRequest.__init__c                 G   s   |r| j | nd| _| S )aC  
        Indicate the fields to be returned in the response. These fields are
        returned in addition to any others implicitly specified.

        ### Parameters

        - **fields**: If fields not specified, all the fields will be loaded.
        Otherwise, fields should be given in the format of `@field`.
        T)r)   extendr*   )r   fieldsr   r   r   loadq   s    
zAggregateRequest.loadc                 G   s   t |tr|gn|}t |tr$|gn|}dtt|f|}|D ]B}|d|jtt|jg7 }||j |jdk	r@|d|jg7 }q@| j| | S )a|  
        Specify by which fields to group the aggregation.

        ### Parameters

        - **fields**: Fields to group by. This can either be a single string,
            or a list of strings. both cases, the field should be specified as
            `@field`.
        - **reducers**: One or more reducers. Reducers may be found in the
            `aggregation` module.
        ZGROUPBYREDUCENAS)	
isinstancer
   r   lenr   r   r0   r   r(   )r   r1   ZreducersretZreducerr   r   r   group_by   s    
zAggregateRequest.group_byc                 K   s>   |  D ]0\}}d|g}|dk	r,|d|g7 }| j| q| S )aQ  
        Specify one or more projection expressions to add to each result

        ### Parameters

        - **kwexpr**: One or more key-value pairs for a projection. The key is
            the alias for the projection, and the value is the projection
            expression itself, for example `apply(square_root="sqrt(@foo)")`
        ZAPPLYNr4   )itemsr(   r0   )r   Zkwexprr   exprr7   r   r   r   apply   s    
zAggregateRequest.applyc                 C   s   t ||}| j|  | S )a  
        Sets the limit for the most recent group or query.

        If no group has been defined yet (via `group_by()`) then this sets
        the limit for the initial pool of results from the query. Otherwise,
        this limits the number of items operated on from the previous group.

        Setting a limit on the initial search results may be useful when
        attempting to execute an aggregation on a sample of a large data set.

        ### Parameters

        - **offset**: Result offset from which to begin paging
        - **num**: Number of results to return


        Example of sorting the initial results:

        ```
        AggregateRequest("@sale_amount:[10000, inf]")            .limit(0, 10)            .group_by("@state", r.count())
        ```

        Will only group by the states found in the first 10 results of the
        query `@sale_amount:[10000, inf]`. On the other hand,

        ```
        AggregateRequest("@sale_amount:[10000, inf]")            .limit(0, 1000)            .group_by("@state", r.count()            .limit(0, 10)
        ```

        Will group all the results matching the query, but only return the
        first 10 groups.

        If you only wish to return a *top-N* style query, consider using
        `sort_by()` instead.

        )r   r(   r0   r   )r   r   numZ_limitr   r   r   limit   s    *
zAggregateRequest.limitc                 O   s   t |ttfr|g}g }|D ]*}t |tr<||j|jg7 }q||g7 }qdtt|g}|| |dd}|dkr|dt|g7 }| j| | S )a,  
        Indicate how the results should be sorted. This can also be used for
        *top-N* style queries

        ### Parameters

        - **fields**: The fields by which to sort. This can be either a single
            field or a list of fields. If you wish to specify order, you can
            use the `Asc` or `Desc` wrapper classes.
        - **max**: Maximum number of results to return. This can be
            used instead of `LIMIT` and is also faster.


        Example of sorting by `foo` ascending and `bar` descending:

        ```
        sort_by(Asc("@foo"), Desc("@bar"))
        ```

        Return the top 10 customers:

        ```
        AggregateRequest()            .group_by("@customer", r.sum("@paid").alias(FIELDNAME))            .sort_by(Desc("@paid"), max=10)
        ```
        ZSORTBYmaxr   MAX)	r5   r
   r   r   r    r6   r0   getr(   )r   r1   kwargsZfields_argsfr7   r>   r   r   r   sort_by   s    

zAggregateRequest.sort_byc                 C   s.   t |tr|g}|D ]}| jd|g q| S )z
        Specify filter for post-query results using predicates relating to
        values in the result set.

        ### Parameters

        - **fields**: Fields to group by. This can either be a single string,
            or a list of strings.
        ZFILTER)r5   r
   r(   r0   )r   ZexpressionsZ
expressionr   r   r   filter	  s
    

zAggregateRequest.filterc                 C   s
   d| _ | S )z|
        If set, the `schema` property will contain a list of `[field, type]`
        entries in the result object.
        T)r+   r   r   r   r   with_schema  s    zAggregateRequest.with_schemac                 C   s
   d| _ | S )NT)r,   r   r   r   r   verbatim#  s    zAggregateRequest.verbatimr           c                 C   s<   dg}|r|dt |g7 }|r2|dt |d g7 }|| _| S )NZ
WITHCURSORCOUNTMAXIDLEi  )r
   r-   )r   r   max_idler   r   r   r   cursor'  s    zAggregateRequest.cursorc                 C   s   | j g}| jr|d | jr(|d | jr8|| j7 }| jrT|d |d n0| jr|d |tt| j |	| j | j
r|	d| j
g |	| j |S )NZ
WITHSCHEMAZVERBATIMZLOADr&   ZDIALECT)r'   r+   appendr,   r-   r*   r)   r
   r6   r0   r.   r(   )r   r7   r   r   r   r   0  s$    




zAggregateRequest.build_argsc                 C   s
   || _ | S )z
        Add a dialect field to the aggregate command.

        - **dialect** - dialect version to execute the query under
        )r.   )r   dialectr   r   r   rM   L  s    zAggregateRequest.dialectN)r&   )r   rG   )r   r   r   r   r	   r2   r8   r;   r=   rC   rD   rE   rF   rK   r   rM   r   r   r   r   r%   U   s   
./
	r%   c                   @   s   e Zd Zdd Zdd ZdS )Cursorc                 C   s   || _ d| _d| _d S )Nr   )cidrJ   r   r   rO   r   r   r   r	   W  s    zCursor.__init__c                 C   s@   t | jg}| jr$|dt | jg7 }| jr<|dt | jg7 }|S )NrI   rH   )r
   rO   rJ   r   r   r   r   r   r   \  s    zCursor.build_argsNr   r   r   r   r   rN   V  s   rN   c                   @   s   e Zd Zdd Zdd ZdS )AggregateResultc                 C   s   || _ || _|| _d S r   )rowsrK   schema)r   rR   rK   rS   r   r   r   r	   f  s    zAggregateResult.__init__c              	   C   s@   | j r| j jnd}d| jj dt| ddt| j d| d	S )N<z at 0xxz Rows=z	, Cursor=>)rK   rO   	__class__r   idr6   rR   rP   r   r   r   __repr__k  s    ,zAggregateResult.__repr__N)r   r   r   r	   rZ   r   r   r   r   rQ   e  s   rQ   N)
objectr   r   r   r   r!   r$   r%   rN   rQ   r   r   r   r   <module>   s   *  