U
    W+duj                     @   s   d dl Z d dlZd dlmZ d dlZd dlmZ d dlmZ d dl	m
Z
mZ d dlmZmZmZ d dlmZmZ d dlmZmZmZ d	ZG d
d deZG dd deZG dd deZdS )    N)
find_class)Key)Blob)ListPropertyMapProperty)datetimedatetime)SDBPersistenceErrorS3ResponseError)mapsix	long_typez%Y-%m-%dT%H:%M:%SZc                   @   s   e Zd ZdS )TimeDecodeErrorN)__name__
__module____qualname__ r   r   B/tmp/pip-unpacked-wheel-dlxw5sjy/boto/sdb/db/manager/sdbmanager.pyr   $   s   r   c                   @   s   e Zd Z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 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% Zd&d' Zd(d) Zd*d+ Zd,d- ZeZd.d/ Zd0d1 Zd2d3 Zd4d5 Zd6d7 Zd8d9 Z d:d; Z!d<S )=SDBConvertera  
    Responsible for converting base Python types to format compatible
    with underlying database.  For SimpleDB, that means everything
    needs to be converted to a string when stored in SimpleDB and from
    a string when retrieved.

    To convert a value, pass it to the encode or decode method.  The
    encode method will take a Python native value and convert to DB
    format.  The decode method will take a DB format value and convert
    it to Python native format.  To find the appropriate method to
    call, the generic encode/decode methods will look for the
    type-specific method by searching for a method
    called"encode_<type name>" or "decode_<type name>".
    c                 C   s   ddl m} || _|| _t| j| jft| j| j	ft
| j| jf| j| j| jft| j| jft| j| jft| j| jft| j| jft| j| jft| j| jfi
| _t j!r| j"| j#f| jt$< d S )Nr   )Model)%Zboto.sdb.db.modelr   model_classmanagerboolencode_booldecode_boolint
encode_int
decode_intfloatencode_floatdecode_floatencode_referencedecode_referencer   r   encode_datetimedecode_datetimer   encode_datedecode_dater	   encode_timedecode_timer   encode_blobdecode_blobstrencode_stringdecode_stringtype_mapr   PY2encode_longdecode_longlong)selfr   r   r   r   r   __init__7   s6     
 
  
 
 
 
 
 
zSDBConverter.__init__c                 C   sJ   z| j | kr| j }W n   Y nX || jkrF| j| d }||S |S )Nr   )r   mror/   )r4   	item_typevalueencoder   r   r   r9   L   s    

zSDBConverter.encodec                 C   s$   || j kr | j | d }||S |S )N   )r/   )r4   r7   r8   decoder   r   r   r;   W   s    
zSDBConverter.decodec                 C   s^   |d g fkrg S t |ts0t|d}| ||S i }t|D ]\}}||d| < q<| ||S )Nr7   %03d)
isinstancelistgetattrr9   	enumerate
encode_map)r4   propr8   r7   valueskvr   r   r   encode_list]   s    

zSDBConverter.encode_listc                 C   s   dd l }|d krd S t|ts.tdt| g }|D ]R}t|d}| j| krX| j}| ||| }|d k	r6|	d|
||f  q6|S )Nr   zExpected a dict value, got %sr7   z%s:%s)urllibr=   dict
ValueErrortyper?   r   r6   r9   appendquote)r4   rB   r8   rG   	new_valuekeyr7   Zencoded_valuer   r   r   rA   n   s    

zSDBConverter.encode_mapc                 C   s>   t |tr| ||S t |tr,| ||S | |j|S d S N)r=   r   rF   r   rA   r9   	data_typer4   rB   r8   r   r   r   encode_prop~   s
    

zSDBConverter.encode_propc                 C   s|   t |ts|g}t|drxt|d}i }|D ]B}|d k	r,| ||\}}zt|}W n   |}Y nX |||< q,| }|S Nr7   )r=   r>   hasattrr?   decode_map_elementr   rC   )r4   rB   r8   r7   Zdec_valvalrD   rE   r   r   r   decode_list   s    




zSDBConverter.decode_listc                 C   sD   t |ts|g}i }t|d}|D ]}| ||\}}|||< q"|S rS   )r=   r>   r?   rU   )r4   rB   r8   Z	ret_valuer7   rV   rD   rE   r   r   r   
decode_map   s    


zSDBConverter.decode_mapc                 C   s\   ddl }|}d|kr.|dd\}}||}| j| krH||d}n| ||}||fS )z!Decode a single element for a mapr   N:r:   )id)rG   splitunquoter   r6   r;   )r4   r7   r8   rG   rN   r   r   r   rU      s    
zSDBConverter.decode_map_elementc                 C   s>   t |tr| ||S t |tr,| ||S | |j|S d S rO   )r=   r   rW   r   rX   r;   rP   rQ   r   r   r   decode_prop   s
    

zSDBConverter.decode_propc                 C   s   t |}|d7 }d| S )N        z%010d)r   r4   r8   r   r   r   r      s    zSDBConverter.encode_intc                 C   sF   zt |}W n    tjd|  d}Y nX t |}|d8 }t |S )NzError, %s is not an integerr   r^   )r   botologerrorr_   r   r   r   r      s    
zSDBConverter.decode_intc                 C   s   t |}|d7 }d| S )N            z%020dr   r_   r   r   r   r1      s    zSDBConverter.encode_longc                 C   s   t |}|d8 }|S )Nrc   rd   r_   r   r   r   r2      s    zSDBConverter.decode_longc                 C   s$   |dkst | dkrdS dS d S )NT)trueyesre   false)r,   lowerr_   r   r   r   r      s    zSDBConverter.encode_boolc                 C   s   |  dkrdS dS d S )Nre   TF)rh   r_   r   r   r   r      s    zSDBConverter.decode_boolc                 C   s0  d| }| d}|d dd}|d }|dkr<d}d	}n|d d
krn|d dkrnd}|dd dd}n|d d
kr|d d
krd}dt| }d| }n|d d
kr|d d
krd}ddt|  }|dd}|dd dd}n4d}ddt|  }|dd}dt| }d| }d|||f S )zM
        See http://tools.ietf.org/html/draft-wood-ldapext-float-00.
        z%eer      0r:           3Z000-+5N   4  r<   2%f
   1z%s %s %s)r[   ljustrjustr   r   )r4   r8   slmantissaexponentcaser   r   r   r       s2    

zSDBConverter.encode_floatc                 C   s   |d }|dd }|dd  }|dkr,dS |dkr6n`|dkrPd	t |d
  }nF|dkrrdt|d  }d| }n$dt|d  }d	tt |d
  }t|d | S )Nr            rm   rl   rp   rr   r<   rs   rt   ru   rv   rn   ri   )r   r   abs)r4   r8   r~   r}   r|   r   r   r   r!      s    
zSDBConverter.decode_floatc                 C   s0   t |tjr|S t |tr$|tS | S d S rO   )r=   r   string_typesr   strftimeISO8601	isoformatr_   r   r   r   r$     s
    

zSDBConverter.encode_datetimec                 C   s   |dkr|S zld|krFd|kr6t |dd dW S t |tW S n0|d}tt|d t|d t|d W S W n tk
r   Y dS X dS )	z'Handles both Dates and DateTime objectsNT.r   z%Y-%m-%dT%H:%M:%Srn   r:   r   )r   strptimer[   r   r   r   	Exceptionr_   r   r   r   r%     s    
*zSDBConverter.decode_datetimec                 C   s   t |tjr|S | S rO   )r=   r   r   r   r_   r   r   r   r&   %  s    zSDBConverter.encode_datec                 C   sD   z0| d}tt|d t|d t|d W S    Y d S X d S )Nrn   r   r:   r   )r[   r   r   r_   r   r   r   r'   *  s
    
&zSDBConverter.decode_datec                 C   s`   d|ksd|krt d| |d}tt|d d}t|dkrX|t|d  t| S )	a   converts strings in the form of HH:MM:SS.mmmmmm
            (created by datetime.time.isoformat()) to
            datetime.time objects.

            Timzone-aware strings ("HH:MM:SS.mmmmmm+HH:MM") won't
            be handled right now and will raise TimeDecodeError.
        rn   ro   z'Can't handle timezone aware objects: %rr   r   rY   r   r:   )r   r[   r   r   lenrK   r	   )r4   r8   tmpargr   r   r   r)   3  s    
zSDBConverter.decode_timec                 C   s&   |dkrd S t |tjr|S |jS d S )N)NNone  )r=   r   r   rZ   r_   r   r   r   r"   D  s
    zSDBConverter.encode_referencec                 C   s   |r|dkrd S |S )Nr   r   r_   r   r   r   r#   L  s    zSDBConverter.decode_referencec                 C   s   |sd S t |tjr|S |jsP| j }|tt	 }d|j
j|jf |_nPtd|j}|r| j }|j|ddd}||d}ntd|j |jd k	r||j |jS )N
s3://%s/%s^s3:\/\/([^\/]*)\/(.*)$r:   Fvalidater   zInvalid Blob ID: %s)r=   r   r   rZ   r   get_blob_bucketZnew_keyr,   uuiduuid4bucketnamerematchget_s3_connection
get_bucketgroupget_keyr
   r8   Zset_contents_from_string)r4   r8   r   rN   r   s3r   r   r   r*   Q  s"    


zSDBConverter.encode_blobc              
   C   s   |sd S t d|}|r| j }|j|ddd}z||d}W q tk
r~ } z|jdkrh W Y d S d }~X Y qX nd S |rt	|d|j
j|jf dS d S d S )	Nr   r:   Fr   r   	Forbiddenr   )filerZ   )r   r   r   r   r   r   r   r   reasonr   r   r   )r4   r8   r   r   r   rN   ri   r   r   r   r+   h  s     

zSDBConverter.decode_blobc              
   C   sZ   t |ts|S zt|dW S    g }|D ]}|tt| q,d| Y S X dS )z/Convert ASCII, Latin-1 or UTF-8 to pure Unicodezutf-8r   N)r=   r,   r   	text_typerK   unichrordjoin)r4   r8   Zarrchr   r   r   r-   |  s    
zSDBConverter.encode_stringc                 C   s   |S )zHDecoding a string is really nothing, just
        return the value as-isr   r_   r   r   r   r.     s    zSDBConverter.decode_stringN)"r   r   r   __doc__r5   r9   r;   rF   rA   rR   rW   rX   rU   r]   r   r   r1   r2   r   r   r    r!   r$   r%   r&   r'   r(   r)   r"   r#   r*   r+   r-   r.   r   r   r   r   r   (   s>   

r   c                   @   s   e Zd Zd7ddZedd Zedd Zdd	 Zd
d Zdd Z	dd Z
dd Zd8ddZdd Zd9ddZdd Zdd Zd:ddZdd  Zd;d!d"Zd#d$ Zd%d& Zd<d'd(Zd)d* Zd+d, Zd-d. Zd/d0 Zd1d2 Zd3d4 Zd5d6 ZdS )=
SDBManagerNc                 C   sz   || _ || _|| _|| _|| _|| _|| _|| _|	| _d | _	d | _
t| | _d | _d | _|
d krpt|drp|j}
|
| _d S )N__consistent__)clsdb_namedb_user	db_passwddb_hostdb_portdb_tableddl_dir
enable_sslr   r   r   	converter_sdb_domainrT   r   
consistent)r4   r   r   r   r   r   r   r   r   r   r   r   r   r   r5     s"    
zSDBManager.__init__c                 C   s   | j d kr|   | j S rO   )r   _connectr4   r   r   r   sdb  s    
zSDBManager.sdbc                 C   s   | j d kr|   | j S rO   )r   r   r   r   r   r   domain  s    
zSDBManager.domainc                    s   t  j j jd}z( fddtj D d }||d< W n tk
rP   Y nX tjf | _	 j	j
 jdd _ js j	 j _d S )N)aws_access_key_idZaws_secret_access_keyZ	is_securec                    s   g | ]}|j  jkr|qS r   )Zendpointr   ).0xr   r   r   
<listcomp>  s      z'SDBManager._connect.<locals>.<listcomp>r   regionFr   )rH   r   r   r   r`   r   Zregions
IndexErrorZconnect_sdbr   lookupr   r   Zcreate_domain)r4   argsr   r   r   r   r     s    zSDBManager._connectc                 c   s(   |D ]}|  ||j|}|r|V  qd S rO   )
get_objectr   )r4   r   Zquery_listeritemobjr   r   r   _object_lister  s    zSDBManager._object_listerc                 C   s&   |d krd S |st |S | j||S rO   )r,   r   rR   rQ   r   r   r   encode_value  s
    zSDBManager.encode_valuec                 C   s   | j ||S rO   )r   r]   rQ   r   r   r   decode_value  s    zSDBManager.decode_valuec                 C   s   | j st| j| j| _ | j S rO   )r   r`   Z
connect_s3r   r   r   r   r   r   r     s    zSDBManager.get_s3_connectionc                 C   sR   |   }d|j| jjf }| }z||| _W n   ||| _Y nX | jS )Nz%s-%s)r   r   r   r   rh   r   r   Zcreate_bucket)r4   Zbucket_namer   r   r   r   r     s    zSDBManager.get_blob_bucketc                 C   s   |j s| jj|j| jd}d|kr|jddD ]l}|j|kr.| |||j }||}zt	||j| W q. t
k
r } ztj| W 5 d }~X Y q.X q.d|_ d S )NZconsistent_read__type__FhiddenT)_loadedr   get_attributesrZ   r   
propertiesr   r   make_value_from_datastoresetattrr   r`   ra   	exception)r4   r   arB   r8   ri   r   r   r   load_object  s    

 zSDBManager.load_objectc           	      C   s   d }|s| j j|| jd}d|kr|r4|d |jkrFt|d |d }|ri }|jddD ]4}|j|krZ| |||j }||}|||j< qZ||f|}d|_	n&d||d |d f }t
jd|  |S )	Nr   r   r   Fr   Tz(%s) class %s.%s not foundzsdbmanager: %s)r   r   r   r   r   r   r   r   r   r   r`   ra   info)	r4   r   rZ   r   r   paramsrB   r8   rz   r   r   r   r     s$    

zSDBManager.get_objectc                 C   s   |  d |S rO   )r   )r4   rZ   r   r   r   get_object_from_id  s    zSDBManager.get_object_from_idc                 C   sb   d| j j| |j|j|j|jf }|jr8|d|j 7 }| j j||j|jd}||_	| 
|j|S )Nzselect * from `%s` %sz	 limit %s)Z	max_items
next_token)r   r   _build_filter_partr   filterssort_byselectlimitr   rsr   )r4   queryZ	query_strr   r   r   r   r     s    $zSDBManager.queryTc           	      C   sR   d| j j| ||||f }d}| j |D ] }|t|d 7 }|r,|  S q,|S )zX
        Get the number of results that would
        be returned in this query
        zselect count(*) from `%s` %sr   ZCount)r   r   r   r   r   )	r4   r   r   Zquickr   r   r   countrowr   r   r   r     s    
zSDBManager.countc                 C   s   |dkrd}|dkrd| }|d krL|dkr8dd|i S |dkrHd| S d	}|j tkr|dkrdd
}n|dkrpd}|dkr|dsd| }d|||ddf S )N__id__
itemName()z`%s`)is=z%(name)s is nullr   )zis not!=z%s is not nullr   like)r   notnot like)r   r   %z%%:%sz
%s %s '%s''z'')	__class__r   
startswithreplace)r4   propertyr   oprV   r   r   r   _build_filter   s$    
zSDBManager._build_filterc                 C   s  ddl }g }d}|r6|d dkr2d}|dd }nd}|rX|rJ||krJd}|d	|  t|tjrd
||jf }	|dkr|	d| 7 }	n|dk	r|	d||f 7 }	|	S |D ]N}
g }|
d }t|ts|g}|D ]}| dd\}}|
d }|	|}||krd}|
|tkrg }|D ]X}| ||}t|tr`|D ]}|| |||| q@n|| |||| q |d	d|  q| ||}t|tr|D ]}|| |||| qq|| |||| q|d	d|  qd|j }| | D ]}|d| 7 }q|d7 }|| d}|rv|sV|d|  |dkrjd| }nd||f }t|dkrdd||f S dS dS )z'
        Build the filter part
        r   NFrn   ZDESCr:   ASCTz(%s)zWHERE %s AND `__type__` = '%s')r   r   z ORDER BY itemName() %sz ORDER BY `%s` %sr   z OR z or z(`__type__` = '%s'z or `__type__` = '%s')r   z`%s` LIKE '%%'zWHERE %s %sz AND )typesrK   r=   r   r   r   r>   stripr[   find_propertyZTypeTyper   r   r   _get_all_decendentskeysr   )r4   r   r   Zorder_byr   r   Zquery_partsZorder_by_filteredZorder_by_methodr   filterZfilter_partsZfilter_propsZfilter_propr   r   r8   r   Zfilter_parts_subrV   rE   Z
type_querysubclassZorder_by_queryr   r   r   r   5  sx    








zSDBManager._build_filter_partc                 C   s.   i }|j D ]}|||j< || | q
|S )z$Get all decendents for a given class)Z__sub_classes__r   updater   )r4   r   Z
decendentsZscr   r   r   r     s
    

zSDBManager._get_all_decendentsc                 O   s   t dd S )Nz%GQL queries not supported in SimpleDB)NotImplementedError)r4   Zquery_stringr   kwdsr   r   r   	query_gql  s    zSDBManager.query_gqlc              	   C   s^  |j stt |_ |jj|jj| d}g }|jddD ]}|	|}|d k	r^| 
||}|g krjd }|d kr||j q<|||j< |jr<z8|j|i}t|jf |}|j |j krtd|j W q< tk
r   Y q<X q<|r&||d }	|d }
|
d k	rt|
ts| 
|	|
}
|
|d< | jj|j |d|d t|dkrZ| j|j | |S )	N)r   r   Z__lineage__Fr   Error: %s must be unique!r   r:   T)r   expected_value)rZ   r,   r   r   r   r   r   Zget_lineager   get_value_for_datastorer   rK   r   uniquenextfindr
   StopIterationr   r=   r   r   put_attributesr   delete_attributes)r4   r   r  attrsZ	del_attrsr   r8   r   obj2rB   rE   r   r   r   save_object  sF    


zSDBManager.save_objectc                 C   s   | j |j d S rO   r   r	  rZ   r4   r   r   r   r   delete_object  s    zSDBManager.delete_objectc                 C   s   t ||| ||}| ||}|jrvz8|j|i}t|jf |}|j|jkr^td|j W n t	k
rt   Y nX | j
j|j||idd d S )Nr  Tr   )r   r  r   r  r   r  r  rZ   r
   r  r   r  )r4   rB   r   r   r8   r   r  r   r   r   set_property  s    

zSDBManager.set_propertyc                 C   sX   | j j|j| jd}||krH| ||| }||}t||j| |S td| d S )Nr   z%s not found)	r   r   rZ   r   r   r   r   r   AttributeError)r4   rB   r   r   r   r8   r   r   r   get_property  s    
zSDBManager.get_propertyc                 C   s   | j j|j||idd d S )NTr  )r   r  rZ   )r4   r   r   r8   r   r   r   set_key_value  s    zSDBManager.set_key_valuec                 C   s   | j |j| d S rO   r  )r4   r   r   r   r   r   delete_key_value  s    zSDBManager.delete_key_valuec                 C   s.   | j j|j|| jd}||kr&|| S d S d S )Nr   )r   r   rZ   r   )r4   r   r   r   r   r   r   get_key_value  s    zSDBManager.get_key_valuec                 C   s   | j |jS rO   )r   Zget_itemrZ   r  r   r   r   get_raw_item  s    zSDBManager.get_raw_item)N)N)N)TNN)NN)N)r   r   r   r5   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r  r  r  r  r  r  r  r  r   r   r   r   r     s:    







R
&r   )r`   r   Z
boto.utilsr   r   Zboto.sdb.db.keyr   Zboto.sdb.db.blobr   Zboto.sdb.db.propertyr   r   r   r   r	   Zboto.exceptionr
   r   Zboto.compatr   r   r   r   r   r   objectr   r   r   r   r   r   <module>   s     k