U
    W+d                      @   sb   d dl mZ d dlmZ G dd deZdddZddd	ZdddZedZ	G dd deZ
dS )    )SDBResponseError)sixc                   @   s0   e Zd ZdZd Z d
ddZdddZdd	 ZdS )SequenceGeneratora  Generic Sequence Generator object, this takes a single
    string as the "sequence" and uses that to figure out
    what the next value in a string is. For example
    if you give "ABC" and pass in "A" it will give you "B",
    and if you give it "C" it will give you "AA".

    If you set "rollover" to True in the above example, passing
    in "C" would give you "A" again.

    The Sequence string can be a string or any iterable
    that has the "index" function and is indexable.
    Fc                 C   s:   || _ t|d | _|| _|d | _d| jj|f | _dS )a  Create a new SequenceGenerator using the sequence_string
        as how to generate the next item.

        :param sequence_string: The string or list that explains
        how to generate the next item in the sequence
        :type sequence_string: str,iterable

        :param rollover: Rollover instead of incrementing when
        we hit the end of the sequence
        :type rollover: bool
        r   z%s('%s')N)sequence_stringlensequence_lengthrollover	last_item	__class____name__)selfr   r	    r   8/tmp/pip-unpacked-wheel-dlxw5sjy/boto/sdb/db/sequence.py__init__(   s
    
zSequenceGenerator.__init__Nc                 C   s   |dkst || jk r | jd S || j d }| jsd|| jkrdd| |d| j  | |f }nd|d| j  | |f }|S )z"Get the next value in the sequenceNr   z%s%s)r   r   r   r	   r
   _inc)r   vallast
last_valuer   r   r   __call__:   s    
$zSequenceGenerator.__call__c                 C   s2   t || jkst| j| j|d t | j  S )zIncrement a single value   )r   r   AssertionErrorr   indexr   r   r   r   r   r   H   s    zSequenceGenerator._inc)F)N)r   
__module____qualname____doc__r   r   r   r   r   r   r   r      s
   

r   Nc                 C   s   | d krdS | d S )Nr   r   r   Zcvlvr   r   r   increment_by_oneQ   s    r   c                 C   s   | d krdS | d S )Nr      r   r   r   r   r   doubleV   s    r!   r   c                 C   s    | dkrd} |dkrd}| | S )z@The fibonacci sequence, this incrementer uses the
    last valueNr   r   r   r   r   r   r   fib[   s
    r"   ABCDEFGHIJKLMNOPQRSTUVWXYZc                   @   sd   e Zd ZdZddedfddZdd Zdd ZeeeZ	d	d
 Z
dd ZeeZdd Zdd ZdS )SequencezA simple Sequence using the new SDB "Consistent" features
    Based largly off of the "Counter" example from mitch garnaat:
    http://bitbucket.org/mitch/stupidbototricks/src/tip/counter.pyNc                 C   s   d| _ d| _d| _|| _|| _|dkr.||}| jdkrNddl}t| | _t|d| _	d| _
t|tjrddlm} ||}|| _| js|| _dS )an  Create a new Sequence, using an optional function to
        increment to the next number, by default we just increment by one.
        Every parameter here is optional, if you don't specify any options
        then you'll get a new SequenceGenerator with a random ID stored in the
        default domain that increments by one and uses the default botoweb
        environment

        :param id: Optional ID (name) for this counter
        :type id: str

        :param domain_name: Optional domain name to use, by default we get this out of the
            environment configuration
        :type domain_name:str

        :param fnc: Optional function to use for the incrementation, by default we just increment by one
            There are several functions defined in this module.
            Your function must accept "None" to get the initial value
        :type fnc: function, str

        :param init_val: Initial value, by default this is the first element in your sequence,
            but you can pass in any value, even a string if you pass in a function that uses
            strings instead of ints to increment
        Nr   )
find_class)_db_valuer   domain_nameiduuidstrZuuid4type	item_type	timestamp
isinstancer   string_typesZ
boto.utilsr%   fncr   )r   r)   r(   r1   Zinit_valr*   r%   r   r   r   r   l   s$    
zSequence.__init__c              
   C   s   ddl }|  }g }i }||d< | jdk	rB| j|d< dt| jg}||d< z"| jj| j||d |d | _W n8 tk
r } z|jdkrt	dn W 5 d}~X Y nX dS )	zSet the valuer   Nr.   r   current_value)expected_valuei  zSequence out of sync)
timer'   r+   dbZput_attributesr)   r.   r   status
ValueError)r   r   r4   nowr3   new_valer   r   r   set   s     



zSequence.setc                 C   sj   | j j| jdd}|rdd|kr(|d | _d|kr@| |d | _d|krd|d dk	rd| |d | _| jS )zGet the valueT)Zconsistent_readr.   r2   r   N)r5   Zget_attributesr)   r.   r-   r'   r   r   r   r   r   get   s    
zSequence.getc                 C   s&   d| j j| j| j| jj| jj| jf S )Nz%s('%s', '%s', '%s.%s', '%s'))r   r   r)   r(   r1   r   r   r   r   r   r   __repr__   s     zSequence.__repr__c              
   C   s   | j sddl}| }| js:|jdd|jddd| _z|| j| _ W n> tk
r } z |jdkrx|	| j| _ n W 5 d}~X Y nX | j S )zConnect to our domainr   NZDBZsequence_dbZdb_namedefaulti  )
r&   botoZconnect_sdbr(   configr<   Z
get_domainr   r6   Zcreate_domain)r   r@   Zsdbr:   r   r   r   _connect   s    
zSequence._connectc                 C   s   |  | j| j| _| jS )N)r1   r   r   r=   r   r   r   next   s    zSequence.nextc                 C   s   | j | j dS )zRemove this sequenceN)r5   Zdelete_attributesr)   r=   r   r   r   delete   s    zSequence.delete)r   r   r   r   r   r   r;   r<   propertyr   r>   rB   r5   rC   rD   r   r   r   r   r$   g   s   0
	r$   )NN)NN)r   r   )Zboto.exceptionr   Zboto.compatr   objectr   r   r!   r"   Zincrement_stringr$   r   r   r   r   <module>   s   8


	