a
    !f;                     @   s  d Z ddlZddlZddl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
 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 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 ddlmZ ddlmZ ddlmZ ddlmZ ejZedj Z!edj"Z#eefZ$dd Z%dd Z&G dd de'Zdd Z(dd  Z)d!d" Z*d2d#d$Z+d3d&d'Z,d4d(d)Z-d5d*d+Z.d,d- Z/d.d/ Z0d0d1 Z1dS )6z-Google Cloud Bigtable HappyBase table module.    N)_datetime_from_microseconds)_microseconds_from_datetime)	_to_bytes)_total_seconds)GCRuleIntersection)MaxAgeGCRule)MaxVersionsGCRule)_get_column_pairs)_WAL_SENTINELBatch)CellsColumnLimitFilter)ColumnQualifierRegexFilter)FamilyNameRegexFilter)RowFilterChain)RowFilterUnion)RowKeyRegexFilter)TimestampRange)TimestampRangeFilter)Tablez>qc                 C   s   t dd| |dS )aB  Make a row dict for a Thrift cell mapping.

    .. warning::

        This method is only provided for HappyBase compatibility, but does not
        actually work.

    :type cell_map: dict
    :param cell_map: Dictionary with ``fam:col`` strings as keys and ``TCell``
                     instances as values.

    :type include_timestamp: bool
    :param include_timestamp: Flag to indicate if cell timestamps should be
                              included with the output.

    :raises: :class:`NotImplementedError <exceptions.NotImplementedError>`
             always
    zThe Cloud Bigtable API output is not the same as the output from the Thrift server, so this helper can not be implemented.Called withNNotImplementedError)Zcell_mapinclude_timestamp r   `/var/www/html/python-backend/venv/lib/python3.9/site-packages/gcloud/bigtable/happybase/table.pymake_row2   s    r   c                 C   s   t dd| |dS )a'  Make a row dict for sorted Thrift column results from scans.

    .. warning::

        This method is only provided for HappyBase compatibility, but does not
        actually work.

    :type sorted_columns: list
    :param sorted_columns: List of ``TColumn`` instances from Thrift.

    :type include_timestamp: bool
    :param include_timestamp: Flag to indicate if cell timestamps should be
                              included with the output.

    :raises: :class:`NotImplementedError <exceptions.NotImplementedError>`
             always
    r   r   Nr   )sorted_columnsr   r   r   r   make_ordered_rowK   s    r   c                   @   s   e Zd ZdZdd Zdd Zdd Zdd	 Zd$ddZd%ddZ	d&ddZ
d'ddZd
efddZd
d
efddZd
d
defddZdd Zd(ddZd)d d!Zd*d"d#Zd
S )+r   a  Representation of Cloud Bigtable table.

    Used for adding data and

    :type name: str
    :param name: The name of the table.

    :type connection: :class:`Connection <.happybase.connection.Connection>`
    :param connection: The connection which has access to the table.
    c                 C   s2   || _ || _d | _| jd ur.t| j | jj| _d S )N)name
connection_low_level_table_LowLevelTableZ	_instance)selfr    r!   r   r   r   __init__o   s    
zTable.__init__c                 C   s   d| j f S )Nz<table.Table name=%r>)r    r$   r   r   r   __repr__y   s    zTable.__repr__c                 C   s4   | j  }i }t|D ]\}}t|j||< q|S )zRetrieve the column families for this table.

        :rtype: dict
        :returns: Mapping from column family name to garbage collection rule
                  for a column family.
        )r"   Zlist_column_familiessix	iteritems_gc_rule_to_dictgc_rule)r$   Zcolumn_family_mapresultZcol_famZcol_fam_objr   r   r   families|   s
    
zTable.familiesc                 C   s   t ddS )ai  Retrieve the regions for this table.

        .. warning::

            Cloud Bigtable does not give information about how a table is laid
            out in memory, so this method does not work. It is
            provided simply for compatibility.

        :raises: :class:`NotImplementedError <exceptions.NotImplementedError>`
                 always
        zQThe Cloud Bigtable API does not have a concept of splitting a table into regions.Nr   r&   r   r   r   regions   s    zTable.regionsNFc                 C   sP   g }|dur| t| td||d}| jj||d}|du rDi S t||dS )a  Retrieve a single row of data.

        Returns the latest cells in each column (or all columns if ``columns``
        is not specified). If a ``timestamp`` is set, then **latest** becomes
        **latest** up until ``timestamp``.

        :type row: str
        :param row: Row key for the row we are reading from.

        :type columns: list
        :param columns: (Optional) Iterable containing column names (as
                        strings). Each column name can be either

                          * an entire column family: ``fam`` or ``fam:``
                          * a single column: ``fam:col``

        :type timestamp: int
        :param timestamp: (Optional) Timestamp (in milliseconds since the
                          epoch). If specified, only cells returned before the
                          the timestamp will be returned.

        :type include_timestamp: bool
        :param include_timestamp: Flag to indicate if cell timestamps should be
                                  included with the output.

        :rtype: dict
        :returns: Dictionary containing all the latest column values in
                  the row.
        N   versions	timestampfiltersfilter_r   )append_columns_filter_helper_filter_chain_helperr"   read_row_partial_row_to_dict)r$   rowcolumnsr2   r   r3   r5   partial_row_datar   r   r   r<      s    z	Table.rowc                 C   s   |sg S g }|dur"| t| | t| td||d}| jj|d}|  g }|D ]4}	|	|jvrlq\|j|	 }
t|
|d}| |	|f q\|S )aq  Retrieve multiple rows of data.

        All optional arguments behave the same in this method as they do in
        :meth:`row`.

        :type rows: list
        :param rows: Iterable of the row keys for the rows we are reading from.

        :type columns: list
        :param columns: (Optional) Iterable containing column names (as
                        strings). Each column name can be either

                          * an entire column family: ``fam`` or ``fam:``
                          * a single column: ``fam:col``

        :type timestamp: int
        :param timestamp: (Optional) Timestamp (in milliseconds since the
                          epoch). If specified, only cells returned before (or
                          at) the timestamp will be returned.

        :type include_timestamp: bool
        :param include_timestamp: Flag to indicate if cell timestamps should be
                                  included with the output.

        :rtype: list
        :returns: A list of pairs, where the first is the row key and the
                  second is a dictionary with the filtered values returned.
        Nr/   r0   r4   r6   )	r7   r8   _row_keys_filter_helperr9   r"   	read_rowsZconsume_allrowsr;   )r$   rA   r=   r2   r   r3   r5   partial_rows_datar,   row_keycurr_row_datacurr_row_dictr   r   r   rA      s*    

z
Table.rowsc                 C   sZ   t |||d}| jj||d}|du r*g S |j}|d\}	}
||	 |
 }t||dS dS )a  Retrieve multiple versions of a single cell from the table.

        :type row: str
        :param row: Row key for the row we are reading from.

        :type column: str
        :param column: Column we are reading from; of the form ``fam:col``.

        :type versions: int
        :param versions: (Optional) The maximum number of cells to return. If
                         not set, returns all cells found.

        :type timestamp: int
        :param timestamp: (Optional) Timestamp (in milliseconds since the
                          epoch). If specified, only cells returned before (or
                          at) the timestamp will be returned.

        :type include_timestamp: bool
        :param include_timestamp: Flag to indicate if cell timestamps should be
                                  included with the output.

        :rtype: list
        :returns: List of values in the cell (with timestamps if
                  ``include_timestamp`` is :data:`True`).
        )columnr1   r2   r4   N:r6   )r9   r"   r:   _cellssplit_cells_to_pairs)r$   r<   rF   r1   r2   r   r5   r>   cellscolumn_family_idcolumn_qualifierZ
curr_cellsr   r   r   rK      s    zTable.cellsc                 k   s   t |||||||\}}}	| jj||||	d}
|
j}z:|
  t|D ]$}||}t||d}||fV  qFW q4 ty   Y qY q40 q4dS )a  Create a scanner for data in this table.

        This method returns a generator that can be used for looping over the
        matching rows.

        If ``row_prefix`` is specified, only rows with row keys matching the
        prefix will be returned. If given, ``row_start`` and ``row_stop``
        cannot be used.

        .. note::

            Both ``row_start`` and ``row_stop`` can be :data:`None` to specify
            the start and the end of the table respectively. If both are
            omitted, a full table scan is done. Note that this usually results
            in severe performance problems.

        The keyword argument ``filter`` is also supported (beyond column and
        row range filters supported here). HappyBase / HBase users will have
        used this as an HBase filter string. (See the `Thrift docs`_ for more
        details on those filters.) However, Google Cloud Bigtable doesn't
        support those filter strings so a
        :class:`~gcloud.bigtable.row.RowFilter` should be used instead.

        .. _Thrift docs: http://hbase.apache.org/0.94/book/thrift.html

        The arguments ``batch_size``, ``scan_batching`` and ``sorted_columns``
        are allowed (as keyword arguments) for compatibility with
        HappyBase. However, they will not be used in any way, and will cause a
        warning if passed. (The ``batch_size`` determines the number of
        results to retrieve per request. The HBase scanner defaults to reading
        one record at a time, so this argument allows HappyBase to increase
        that number. However, the Cloud Bigtable API uses HTTP/2 streaming so
        there is no concept of a batched scan. The ``sorted_columns`` flag
        tells HBase to return columns in order, but Cloud Bigtable doesn't
        have this feature.)

        :type row_start: str
        :param row_start: (Optional) Row key where the scanner should start
                          (includes ``row_start``). If not specified, reads
                          from the first key. If the table does not contain
                          ``row_start``, it will start from the next key after
                          it that **is** contained in the table.

        :type row_stop: str
        :param row_stop: (Optional) Row key where the scanner should stop
                         (excludes ``row_stop``). If not specified, reads
                         until the last key. The table does not have to contain
                         ``row_stop``.

        :type row_prefix: str
        :param row_prefix: (Optional) Prefix to match row keys.

        :type columns: list
        :param columns: (Optional) Iterable containing column names (as
                        strings). Each column name can be either

                          * an entire column family: ``fam`` or ``fam:``
                          * a single column: ``fam:col``

        :type timestamp: int
        :param timestamp: (Optional) Timestamp (in milliseconds since the
                          epoch). If specified, only cells returned before (or
                          at) the timestamp will be returned.

        :type include_timestamp: bool
        :param include_timestamp: Flag to indicate if cell timestamps should be
                                  included with the output.

        :type limit: int
        :param limit: (Optional) Maximum number of rows to return.

        :type kwargs: dict
        :param kwargs: Remaining keyword arguments. Provided for HappyBase
                       compatibility.

        :raises: If ``limit`` is set but non-positive, or if ``row_prefix`` is
                 used with row start/stop,
                 :class:`TypeError <exceptions.TypeError>` if a string
                 ``filter`` is used.
        )Z	start_keyend_keylimitr5   r6   N)	_scan_filter_helperr"   r@   rA   Zconsume_nextsortedpopr;   StopIteration)r$   	row_startrow_stop
row_prefixr=   r2   r   rO   kwargsZfilter_chainrB   Z	rows_dictrC   rD   rE   r   r   r   scan+  s$    S

z
Table.scanc                 C   s>   | j ||d}||| W d   n1 s00    Y  dS )a]  Insert data into a row in this table.

        .. note::

            This method will send a request with a single "put" mutation.
            In many situations, :meth:`batch` is a more appropriate
            method to manipulate data since it helps combine many mutations
            into a single request.

        :type row: str
        :param row: The row key where the mutation will be "put".

        :type data: dict
        :param data: Dictionary containing the data to be inserted. The keys
                     are columns names (of the form ``fam:col``) and the values
                     are strings (bytes) to be stored in those columns.

        :type timestamp: int
        :param timestamp: (Optional) Timestamp (in milliseconds since the
                          epoch) that the mutation will be applied at.

        :type wal: object
        :param wal: Unused parameter (to be passed to a created batch).
                    Provided for compatibility with HappyBase, but irrelevant
                    for Cloud Bigtable since it does not have a Write Ahead
                    Log.
        r2   walN)batchput)r$   r<   datar2   rZ   r[   r   r   r   r\     s    z	Table.putc                 C   s>   | j ||d}||| W d   n1 s00    Y  dS )a  Delete data from a row in this table.

        This method deletes the entire ``row`` if ``columns`` is not
        specified.

        .. note::

            This method will send a request with a single delete mutation.
            In many situations, :meth:`batch` is a more appropriate
            method to manipulate data since it helps combine many mutations
            into a single request.

        :type row: str
        :param row: The row key where the delete will occur.

        :type columns: list
        :param columns: (Optional) Iterable containing column names (as
                        strings). Each column name can be either

                          * an entire column family: ``fam`` or ``fam:``
                          * a single column: ``fam:col``

        :type timestamp: int
        :param timestamp: (Optional) Timestamp (in milliseconds since the
                          epoch) that the mutation will be applied at.

        :type wal: object
        :param wal: Unused parameter (to be passed to a created batch).
                    Provided for compatibility with HappyBase, but irrelevant
                    for Cloud Bigtable since it does not have a Write Ahead
                    Log.
        rY   N)r[   delete)r$   r<   r=   r2   rZ   r[   r   r   r   r^     s    !zTable.deletec                 C   s   t | ||||dS )a  Create a new batch operation for this table.

        This method returns a new
        :class:`Batch <.happybase.batch.Batch>` instance that can be
        used for mass data manipulation.

        :type timestamp: int
        :param timestamp: (Optional) Timestamp (in milliseconds since the
                          epoch) that all mutations will be applied at.

        :type batch_size: int
        :param batch_size: (Optional) The maximum number of mutations to allow
                           to accumulate before committing them.

        :type transaction: bool
        :param transaction: Flag indicating if the mutations should be sent
                            transactionally or not. If ``transaction=True`` and
                            an error occurs while a
                            :class:`Batch <.happybase.batch.Batch>` is
                            active, then none of the accumulated mutations will
                            be committed. If ``batch_size`` is set, the
                            mutation can't be transactional.

        :type wal: object
        :param wal: Unused parameter (to be passed to the created batch).
                    Provided for compatibility with HappyBase, but irrelevant
                    for Cloud Bigtable since it does not have a Write Ahead
                    Log.

        :rtype: :class:`Batch <gcloud.bigtable.happybase.batch.Batch>`
        :returns: A batch bound to this table.
        )r2   
batch_sizetransactionrZ   r   )r$   r2   r_   r`   rZ   r   r   r   r[     s    "zTable.batchc                 C   s   | j ||ddS )a  Retrieve the current value of a counter column.

        This method retrieves the current value of a counter column. If the
        counter column does not exist, this function initializes it to ``0``.

        .. note::

            Application code should **never** store a counter value directly;
            use the atomic :meth:`counter_inc` and :meth:`counter_dec` methods
            for that.

        :type row: str
        :param row: Row key for the row we are getting a counter from.

        :type column: str
        :param column: Column we are ``get``-ing from; of the form ``fam:col``.

        :rtype: int
        :returns: Counter value (after initializing / incrementing by 0).
        r   )valuecounter_inc)r$   r<   rF   r   r   r   counter_get  s    zTable.counter_getr   c                 C   s   |  ||t|i dS )a7  Set a counter column to a specific value.

        .. note::

            Be careful using this method. It can be useful for setting the
            initial value of a counter, but it defeats the purpose of using
            atomic increment and decrement.

        :type row: str
        :param row: Row key for the row we are setting a counter in.

        :type column: str
        :param column: Column we are setting a value in; of
                       the form ``fam:col``.

        :type value: int
        :param value: Value to set the counter to.
        N)r\   	_PACK_I64r$   r<   rF   ra   r   r   r   counter_set  s    zTable.counter_setr/   c                 C   s   | j j|dd}t|tjr&|d}|d\}}|||| | }|| | }t	|dkrjt
d|d }|d }	t|	\}
|
S )a  Atomically increment a counter column.

        This method atomically increments a counter column in ``row``.
        If the counter column does not exist, it is automatically initialized
        to ``0`` before being incremented.

        :type row: str
        :param row: Row key for the row we are incrementing a counter in.

        :type column: str
        :param column: Column we are incrementing a value in; of the
                       form ``fam:col``.

        :type value: int
        :param value: Amount to increment the counter by. (If negative,
                      this is equivalent to decrement.)

        :rtype: int
        :returns: Counter value after incrementing.
        T)r7   utf-8rG   r/   z,Expected server to return one modified cell.r   )r"   r<   
isinstancer(   binary_typedecoderI   Zincrement_cell_valuecommitlen
ValueError_UNPACK_I64)r$   r<   rF   ra   rL   rM   Zmodified_cellsZcolumn_cellsZcolumn_cellZbytes_valueZ	int_valuer   r   r   rc   )  s    

zTable.counter_incc                 C   s   |  ||| S )a  Atomically decrement a counter column.

        This method atomically decrements a counter column in ``row``.
        If the counter column does not exist, it is automatically initialized
        to ``0`` before being decremented.

        :type row: str
        :param row: Row key for the row we are decrementing a counter in.

        :type column: str
        :param column: Column we are decrementing a value in; of the
                       form ``fam:col``.

        :type value: int
        :param value: Amount to decrement the counter by. (If negative,
                      this is equivalent to increment.)

        :rtype: int
        :returns: Counter value after decrementing.
        rb   rf   r   r   r   counter_decY  s    zTable.counter_dec)NNF)NNF)NNF)NNNNNFN)r   )r/   )r/   )__name__
__module____qualname____doc__r%   r'   r-   r.   r<   rA   rK   rX   r
   r\   r^   r[   rd   rg   rc   rp   r   r   r   r   r   c   s2   

-  
:  
,   
h$
%

0r   c                 C   s   | }| du ri }nt | tr,dt| ji}nt | trBd| ji}nvt | trt| jdkr| j\}}t |t	rt |t	rt
|}t
|}| \}| \}||kr||| ||| i}|S )a'  Converts garbage collection rule to dictionary if possible.

    This is in place to support dictionary values as was done
    in HappyBase, which has somewhat different garbage collection rule
    settings for column families.

    Only does this if the garbage collection rule is:

    * :class:`gcloud.bigtable.column_family.MaxAgeGCRule`
    * :class:`gcloud.bigtable.column_family.MaxVersionsGCRule`
    * Composite :class:`gcloud.bigtable.column_family.GCRuleIntersection`
      with two rules, one each of type
      :class:`gcloud.bigtable.column_family.MaxAgeGCRule` and
      :class:`gcloud.bigtable.column_family.MaxVersionsGCRule`

    Otherwise, just returns the input without change.

    :type gc_rule: :data:`NoneType <types.NoneType>`,
                   :class:`.GarbageCollectionRule`
    :param gc_rule: A garbage collection rule to convert to a dictionary
                    (if possible).

    :rtype: dict or
            :class:`gcloud.bigtable.column_family.GarbageCollectionRule`
    :returns: The converted garbage collection rule.
    NZtime_to_liveZmax_versions   )ri   r   r   Zmax_ager   Zmax_num_versionsr   rm   rules_SIMPLE_GC_RULESr*   keys)r+   r,   Zrule1Zrule2key1key2r   r   r   r*   q  s(    






r*   c                 C   s    t | |}tt|d ddS )aP  Gets the next character based on a position in a string.

    :type str_val: str
    :param str_val: A string containing the character to update.

    :type index: int
    :param index: An integer index in ``str_val``.

    :rtype: str
    :returns: The next character after the character at ``index``
              in ``str_val``.
    r/   latin-1encoding)r(   
indexbytesr   chr)str_valindexZord_valr   r   r   
_next_char  s    r   c                 C   sj   t | dd} | dkr| S t| d }|dkrHt| |dkr>qH|d8 }q$|dkrTdS | d| t| | S )	a  Increment and truncate a byte string.

    Determines shortest string that sorts after the given string when
    compared using regular string comparison semantics.

    Modeled after implementation in ``gcloud-golang``.

    Increments the last byte that is smaller than ``0xFF``, and
    drops everything after it. If the string only contains ``0xFF`` bytes,
    ``''`` is returned.

    :type str_val: str
    :param str_val: String to increment.

    :rtype: str
    :returns: The next string in lexical order after ``str_val``.
    r{   r|       r/   r      N)r   rm   r(   r~   r   )r   r   r   r   r   _string_successor  s    
r   c                 C   s"   | du rdS t d|  }t|dS )a  Create a timestamp range from an HBase / HappyBase timestamp.

    HBase uses timestamp as an argument to specify an exclusive end
    deadline. Cloud Bigtable also uses exclusive end times, so
    the behavior matches.

    :type timestamp: int
    :param timestamp: (Optional) Timestamp (in milliseconds since the
                      epoch). Intended to be used as the end of an HBase
                      time range, which is exclusive.

    :rtype: :class:`gcloud.bigtable.row.TimestampRange`,
            :data:`NoneType <types.NoneType>`
    :returns: The timestamp range corresponding to the passed in
              ``timestamp``.
    N  )end)r   r   )r2   Znext_timestampr   r   r   _convert_to_time_range  s    r   Fc                 C   sB   g }| D ]4}|r0t |jd }||j|f q||j q|S )a  Converts list of cells to HappyBase format.

    For example::

      >>> import datetime
      >>> from gcloud.bigtable.row_data import Cell
      >>> cell1 = Cell(b'val1', datetime.datetime.utcnow())
      >>> cell2 = Cell(b'val2', datetime.datetime.utcnow())
      >>> _cells_to_pairs([cell1, cell2])
      [b'val1', b'val2']
      >>> _cells_to_pairs([cell1, cell2], include_timestamp=True)
      [(b'val1', 1456361486255), (b'val2', 1456361491927)]

    :type cells: list
    :param cells: List of :class:`gcloud.bigtable.row_data.Cell` returned
                  from a read request.

    :type include_timestamp: bool
    :param include_timestamp: Flag to indicate if cell timestamps should be
                              included with the output.

    :rtype: list
    :returns: List of values in the cell. If ``include_timestamp=True``, each
              value will be a pair, with the first part the bytes value in
              the cell and the second part the number of milliseconds in the
              timestamp on the cell.
    r   )r   r2   r7   ra   )rK   r   r,   cellZ	ts_millisr   r   r   rJ     s    rJ   c                 C   s8   i }t |  D ] \}}t||d}|d ||< q|S )a  Convert a low-level row data object to a dictionary.

    Assumes only the latest value in each row is needed. This assumption
    is due to the fact that this method is used by callers which use
    a ``CellsColumnLimitFilter(1)`` filter.

    For example::

      >>> import datetime
      >>> from gcloud.bigtable.row_data import Cell, PartialRowData
      >>> cell1 = Cell(b'val1', datetime.datetime.utcnow())
      >>> cell2 = Cell(b'val2', datetime.datetime.utcnow())
      >>> row_data = PartialRowData(b'row-key')
      >>> _partial_row_to_dict(row_data)
      {}
      >>> row_data._cells[u'fam1'] = {b'col1': [cell1], b'col2': [cell2]}
      >>> _partial_row_to_dict(row_data)
      {b'fam1:col2': b'val2', b'fam1:col1': b'val1'}
      >>> _partial_row_to_dict(row_data, include_timestamp=True)
      {b'fam1:col2': (b'val2', 1456361724480),
       b'fam1:col1': (b'val1', 1456361721135)}

    :type partial_row_data: :class:`.row_data.PartialRowData`
    :param partial_row_data: Row data consumed from a stream.

    :type include_timestamp: bool
    :param include_timestamp: Flag to indicate if cell timestamps should be
                              included with the output.

    :rtype: dict
    :returns: The row data converted to a dictionary.
    r6   r   )r(   r)   to_dictrJ   )r>   r   r,   rF   rK   Z	cell_valsr   r   r   r;     s    !r;   c           
      C   s   |du rg }| durVt | tjr*| d} | d\}}t|}t|}|||g |durl|t	| t
|d}|dur|t| t|}	|	dkrtdn|	dkr|d S t|dS dS )	af  Create filter chain to limit a results set.

    :type column: str
    :param column: (Optional) The column (``fam:col``) to be selected
                   with the filter.

    :type versions: int
    :param versions: (Optional) The maximum number of cells to return.

    :type timestamp: int
    :param timestamp: (Optional) Timestamp (in milliseconds since the
                      epoch). If specified, only cells returned before (or
                      at) the timestamp will be matched.

    :type filters: list
    :param filters: (Optional) List of existing filters to be extended.

    :rtype: :class:`RowFilter <gcloud.bigtable.row.RowFilter>`
    :returns: The chained filter created, or just a single filter if only
              one was needed.
    :raises: :class:`ValueError <exceptions.ValueError>` if there are no
             filters to chain.
    Nrh   rG   )r2   r   Must have at least one filter.r/   r3   )ri   r(   rj   rk   rI   r   r   extendr7   r   r   r   rm   rn   r   )
rF   r1   r2   r3   rL   rM   
fam_filterqual_filterZ
time_rangenum_filtersr   r   r   r9   =  s(    


r9   c                 C   s  | dd}g }dD ] }	|	|v r||	 | |	 q|rVd|}d|f }
t|
 |rhtd| |dur|dk rtd|dur| dus|durtd	|} t|}g }t|t	j
rtd
n|dur|| |dur|t| td||d}| ||fS )z2Helper for :meth:`scan`:  build up a filter chain.filterN)r_   Zscan_batchingr   z, zRThe HappyBase legacy arguments %s were used. These arguments are unused by gcloud.zReceived unexpected argumentsr/   zlimit must be positivez8row_prefix cannot be combined with row_start or row_stopzoSpecifying filters as a string is not supported by Cloud Bigtable. Use a gcloud.bigtable.row.RowFilter instead.r0   )rR   r7   join_WARN	TypeErrorrx   rn   r   ri   r(   string_typesr8   r9   )rT   rU   rV   r=   r2   rO   rW   r5   Zlegacy_argsZkw_namemessager3   r   r   r   rP   o  s@    



rP   c                 C   s   g }t | D ]D\}}t|}|durFt|}t||gd}|| q|| qt|}|dkrltdn|dkr||d S t|dS dS )a2  Creates a union filter for a list of columns.

    :type columns: list
    :param columns: Iterable containing column names (as strings). Each column
                    name can be either

                      * an entire column family: ``fam`` or ``fam:``
                      * a single column: ``fam:col``

    :rtype: :class:`RowFilter <gcloud.bigtable.row.RowFilter>`
    :returns: The union filter created containing all of the matched columns.
    :raises: :class:`ValueError <exceptions.ValueError>` if there are no
             filters to union.
    Nr   r   r   r/   )r	   r   r   r   r7   rm   rn   r   )r=   r3   rL   rM   r   r   Zcombined_filterr   r   r   r   r8     s     
r8   c                 C   sT   g }| D ]}| t| qt|}|dkr6tdn|dkrF|d S t|dS dS )ax  Creates a union filter for a list of rows.

    :type row_keys: list
    :param row_keys: Iterable containing row keys (as strings).

    :rtype: :class:`RowFilter <gcloud.bigtable.row.RowFilter>`
    :returns: The union filter created containing all of the row keys.
    :raises: :class:`ValueError <exceptions.ValueError>` if there are no
             filters to union.
    r   r   r/   r   N)r7   r   rm   rn   r   )Zrow_keysr3   rC   r   r   r   r   r?     s    
r?   )N)F)F)NNNN)2rt   structwarningsr(   Zgcloud._helpersr   r   r   r   Zgcloud.bigtable.column_familyr   r   r   Zgcloud.bigtable.happybase.batchr	   r
   r   Zgcloud.bigtable.row_filtersr   r   r   r   r   r   r   r   Zgcloud.bigtable.tabler   r#   warnr   Structpackre   unpackro   rw   r   r   objectr*   r   r   r   rJ   r;   r9   rP   r8   r?   r   r   r   r   <module>   sZ       0"

&
+  
2+#