σ
H`ΎTc           @@  sβ   d  d l  m 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 Z d e j f d     YZ d e j f d     YZ e e d <d e f d     YZ e e d <d S(   i    (   t   absolute_importNi   (   t   ischema_namesi   (   t   types(   t	   custom_op(   t   sql(   t   elements(   t   utilt   JSONt   JSONElementt   JSONBc           B@  s8   e  Z d  Z e d d d  Z e d    Z d   Z RS(   sΛ  Represents accessing an element of a :class:`.JSON` value.

    The :class:`.JSONElement` is produced whenever using the Python index
    operator on an expression that has the type :class:`.JSON`::

        expr = mytable.c.json_data['some_key']

    The expression typically compiles to a JSON access such as ``col -> key``.
    Modifiers are then available for typing behavior, including
    :meth:`.JSONElement.cast` and :attr:`.JSONElement.astext`.

    c         C@  sΌ   | |  _  | d  k rf t | d  r] t | t j  r] d } d d j d   | D  } qf d } n  | |  _ t | d d } | j	 | | |  } t
 t |   j | | | d	 | d  S(
   Nt   __iter__s   #>s   {%s}s   , c         s@  s   |  ] } t  j |  Vq d  S(   N(   R   t	   text_type(   t   .0t   elem(    (    si   /var/www/send.findwatt.com/datamanager/lib/python2.7/site-packages/sqlalchemy/dialects/postgresql/json.pys	   <genexpr>+   s    s   ->t
   precedencei   t   type_(   t   _astextt   Nonet   hasattrt
   isinstanceR   t   string_typest   joint   _json_opstringR   t   _check_literalt   superR   t   __init__(   t   selft   leftt   rightt   astextt   opstringt   result_typet   operator(    (    si   /var/www/send.findwatt.com/datamanager/lib/python2.7/site-packages/sqlalchemy/dialects/postgresql/json.pyR   #   s    			c         C@  sI   |  j  r |  St |  j |  j d t d |  j d d t j d t  Sd S(   sκ   Convert this :class:`.JSONElement` to use the 'astext' operator
        when evaluated.

        E.g.::

            select([data_table.c.data['some key'].astext])

        .. seealso::

            :meth:`.JSONElement.cast`

        R   R   t   >R   t   convert_unicodeN(   R   R   R   R   t   TrueR   t   sqltypest   String(   R   (    (    si   /var/www/send.findwatt.com/datamanager/lib/python2.7/site-packages/sqlalchemy/dialects/postgresql/json.pyR   5   s    		c         C@  s-   |  j  s |  j j |  St j |  |  Sd S(   s  Convert this :class:`.JSONElement` to apply both the 'astext' operator
        as well as an explicit type cast when evaulated.

        E.g.::

            select([data_table.c.data['some key'].cast(Integer)])

        .. seealso::

            :attr:`.JSONElement.astext`

        N(   R   R   t   castR   (   R   R   (    (    si   /var/www/send.findwatt.com/datamanager/lib/python2.7/site-packages/sqlalchemy/dialects/postgresql/json.pyR&   N   s    	N(	   t   __name__t
   __module__t   __doc__t   FalseR   R   t   propertyR   R&   (    (    (    si   /var/www/send.findwatt.com/datamanager/lib/python2.7/site-packages/sqlalchemy/dialects/postgresql/json.pyR      s
   c           B@  sN   e  Z d  Z d Z e d  Z d e j j f d     YZ	 d   Z
 d   Z RS(   s	  Represent the Postgresql JSON type.

    The :class:`.JSON` type stores arbitrary JSON format data, e.g.::

        data_table = Table('data_table', metadata,
            Column('id', Integer, primary_key=True),
            Column('data', JSON)
        )

        with engine.connect() as conn:
            conn.execute(
                data_table.insert(),
                data = {"key1": "value1", "key2": "value2"}
            )

    :class:`.JSON` provides several operations:

    * Index operations::

        data_table.c.data['some key']

    * Index operations returning text (required for text comparison)::

        data_table.c.data['some key'].astext == 'some value'

    * Index operations with a built-in CAST call::

        data_table.c.data['some key'].cast(Integer) == 5

    * Path index operations::

        data_table.c.data[('key_1', 'key_2', ..., 'key_n')]

    * Path index operations returning text (required for text comparison)::

        data_table.c.data[('key_1', 'key_2', ..., 'key_n')].astext == \
            'some value'

    Index operations return an instance of :class:`.JSONElement`, which
    represents an expression such as ``column -> index``.  This element then
    defines methods such as :attr:`.JSONElement.astext` and
    :meth:`.JSONElement.cast` for setting up type behavior.

    The :class:`.JSON` type, when used with the SQLAlchemy ORM, does not
    detect in-place mutations to the structure.  In order to detect these, the
    :mod:`sqlalchemy.ext.mutable` extension must be used.  This extension will
    allow "in-place" changes to the datastructure to produce events which
    will be detected by the unit of work.  See the example at :class:`.HSTORE`
    for a simple example involving a dictionary.

    Custom serializers and deserializers are specified at the dialect level,
    that is using :func:`.create_engine`.  The reason for this is that when
    using psycopg2, the DBAPI only allows serializers at the per-cursor
    or per-connection level.   E.g.::

        engine = create_engine("postgresql://scott:tiger@localhost/test",
                                json_serializer=my_serialize_fn,
                                json_deserializer=my_deserialize_fn
                        )

    When using the psycopg2 dialect, the json_deserializer is registered
    against the database using ``psycopg2.extras.register_default_json``.

    .. versionadded:: 0.9

    R   c         C@  s   | |  _  d S(   s  Construct a :class:`.JSON` type.

        :param none_as_null: if True, persist the value ``None`` as a
         SQL NULL value, not the JSON encoding of ``null``.   Note that
         when this flag is False, the :func:`.null` construct can still
         be used to persist a NULL value::

             from sqlalchemy import null
             conn.execute(table.insert(), data=null())

         .. versionchanged:: 0.9.8 - Added ``none_as_null``, and :func:`.null`
            is now supported in order to persist a NULL value.

         N(   t   none_as_null(   R   R,   (    (    si   /var/www/send.findwatt.com/datamanager/lib/python2.7/site-packages/sqlalchemy/dialects/postgresql/json.pyR   §   s    t   comparator_factoryc           B@  s    e  Z d  Z d   Z d   Z RS(   s0   Define comparison operations for :class:`.JSON`.c         C@  s   t  |  j |  S(   s   Get the value at a given key.(   R   t   expr(   R   t   other(    (    si   /var/www/send.findwatt.com/datamanager/lib/python2.7/site-packages/sqlalchemy/dialects/postgresql/json.pyt   __getitem__»   s    c         C@  sG   t  | t  r. | j d k r. | t j f Sn  t j j j |  | |  S(   Ns   ->(   R   R   R   R$   t   Textt   Concatenablet
   Comparatort   _adapt_expression(   R   t   opt   other_comparator(    (    si   /var/www/send.findwatt.com/datamanager/lib/python2.7/site-packages/sqlalchemy/dialects/postgresql/json.pyR4   ΐ   s
    (   R'   R(   R)   R0   R4   (    (    (    si   /var/www/send.findwatt.com/datamanager/lib/python2.7/site-packages/sqlalchemy/dialects/postgresql/json.pyR-   Έ   s   	c         @  sR   | j  p t j  t j r< | j       f d   } n   f d   } | S(   Nc         @  s>   t  |  t j  s' |  d  k r+  j r+ d  S |   j    S(   N(   R   R   t   NullR   R,   t   encode(   t   value(   t   encodingR   t   json_serializer(    si   /var/www/send.findwatt.com/datamanager/lib/python2.7/site-packages/sqlalchemy/dialects/postgresql/json.pyt   processΜ   s    c         @  s5   t  |  t j  s' |  d  k r+   j r+ d  S |   S(   N(   R   R   R7   R   R,   (   R9   (   R   R;   (    si   /var/www/send.findwatt.com/datamanager/lib/python2.7/site-packages/sqlalchemy/dialects/postgresql/json.pyR<   Σ   s    (   t   _json_serializert   jsont   dumpsR   t   py2kR:   (   R   t   dialectR<   (    (   R:   R   R;   si   /var/www/send.findwatt.com/datamanager/lib/python2.7/site-packages/sqlalchemy/dialects/postgresql/json.pyt   bind_processorΗ   s    		c         @  sL   | j  p t j  t j r9 | j      f d   } n  f d   } | S(   Nc         @  s#   |  d  k r d  S  |  j    S(   N(   R   t   decode(   R9   (   t   json_deserializerR:   (    si   /var/www/send.findwatt.com/datamanager/lib/python2.7/site-packages/sqlalchemy/dialects/postgresql/json.pyR<   ΰ   s    c         @  s   |  d  k r d  S  |   S(   N(   R   (   R9   (   RD   (    si   /var/www/send.findwatt.com/datamanager/lib/python2.7/site-packages/sqlalchemy/dialects/postgresql/json.pyR<   ε   s    (   t   _json_deserializerR>   t   loadsR   R@   R:   (   R   RA   t   coltypeR<   (    (   R:   RD   si   /var/www/send.findwatt.com/datamanager/lib/python2.7/site-packages/sqlalchemy/dialects/postgresql/json.pyt   result_processorΫ   s    		(   R'   R(   R)   t   __visit_name__R*   R   R$   R2   R3   R-   RB   RH   (    (    (    si   /var/www/send.findwatt.com/datamanager/lib/python2.7/site-packages/sqlalchemy/dialects/postgresql/json.pyR   a   s   B	R>   c           B@  s6   e  Z d  Z d Z e Z d e j j f d     YZ	 RS(   s	  Represent the Postgresql JSONB type.

    The :class:`.JSONB` type stores arbitrary JSONB format data, e.g.::

        data_table = Table('data_table', metadata,
            Column('id', Integer, primary_key=True),
            Column('data', JSONB)
        )

        with engine.connect() as conn:
            conn.execute(
                data_table.insert(),
                data = {"key1": "value1", "key2": "value2"}
            )

    :class:`.JSONB` provides several operations:

    * Index operations::

        data_table.c.data['some key']

    * Index operations returning text (required for text comparison)::

        data_table.c.data['some key'].astext == 'some value'

    * Index operations with a built-in CAST call::

        data_table.c.data['some key'].cast(Integer) == 5

    * Path index operations::

        data_table.c.data[('key_1', 'key_2', ..., 'key_n')]

    * Path index operations returning text (required for text comparison)::

        data_table.c.data[('key_1', 'key_2', ..., 'key_n')].astext == \
            'some value'

    Index operations return an instance of :class:`.JSONElement`, which
    represents an expression such as ``column -> index``.  This element then
    defines methods such as :attr:`.JSONElement.astext` and
    :meth:`.JSONElement.cast` for setting up type behavior.

    The :class:`.JSON` type, when used with the SQLAlchemy ORM, does not
    detect in-place mutations to the structure.  In order to detect these, the
    :mod:`sqlalchemy.ext.mutable` extension must be used.  This extension will
    allow "in-place" changes to the datastructure to produce events which
    will be detected by the unit of work.  See the example at :class:`.HSTORE`
    for a simple example involving a dictionary.

    Custom serializers and deserializers are specified at the dialect level,
    that is using :func:`.create_engine`.  The reason for this is that when
    using psycopg2, the DBAPI only allows serializers at the per-cursor
    or per-connection level.   E.g.::

        engine = create_engine("postgresql://scott:tiger@localhost/test",
                                json_serializer=my_serialize_fn,
                                json_deserializer=my_deserialize_fn
                        )

    When using the psycopg2 dialect, the json_deserializer is registered
    against the database using ``psycopg2.extras.register_default_json``.

    .. versionadded:: 0.9.7

    R	   R-   c           B@  sM   e  Z d  Z d   Z d   Z d   Z d   Z d   Z d   Z d   Z	 RS(   s0   Define comparison operations for :class:`.JSON`.c         C@  s   t  |  j |  S(   s   Get the value at a given key.(   R   R.   (   R   R/   (    (    si   /var/www/send.findwatt.com/datamanager/lib/python2.7/site-packages/sqlalchemy/dialects/postgresql/json.pyR0   9  s    c         C@  sc   t  | t  rJ | j d k r+ | t j f S| j d k rJ | t j f Sn  t j j j |  | |  S(   Nt   ?s   ?&s   ?|s   @>s   <@s   ->(   RJ   s   ?&s   ?|s   @>s   <@(	   R   R   R   R$   t   BooleanR1   R2   R3   R4   (   R   R5   R6   (    (    si   /var/www/send.findwatt.com/datamanager/lib/python2.7/site-packages/sqlalchemy/dialects/postgresql/json.pyR4   >  s    c         C@  s   |  j  j d  |  S(   sv   Boolean expression.  Test for presence of a key.  Note that the
            key may be a SQLA expression.
            RJ   (   R.   R5   (   R   R/   (    (    si   /var/www/send.findwatt.com/datamanager/lib/python2.7/site-packages/sqlalchemy/dialects/postgresql/json.pyt   has_keyI  s    c         C@  s   |  j  j d  |  S(   sH   Boolean expression.  Test for presence of all keys in jsonb
            s   ?&(   R.   R5   (   R   R/   (    (    si   /var/www/send.findwatt.com/datamanager/lib/python2.7/site-packages/sqlalchemy/dialects/postgresql/json.pyt   has_allO  s    c         C@  s   |  j  j d  |  S(   sG   Boolean expression.  Test for presence of any key in jsonb
            s   ?|(   R.   R5   (   R   R/   (    (    si   /var/www/send.findwatt.com/datamanager/lib/python2.7/site-packages/sqlalchemy/dialects/postgresql/json.pyt   has_anyT  s    c         K@  s   |  j  j d  |  S(   s   Boolean expression.  Test if keys (or array) are a superset of/contained
            the keys of the argument jsonb expression.
            s   @>(   R.   R5   (   R   R/   t   kwargs(    (    si   /var/www/send.findwatt.com/datamanager/lib/python2.7/site-packages/sqlalchemy/dialects/postgresql/json.pyt   containsY  s    c         C@  s   |  j  j d  |  S(   s|   Boolean expression.  Test if keys are a proper subset of the
            keys of the argument jsonb expression.
            s   <@(   R.   R5   (   R   R/   (    (    si   /var/www/send.findwatt.com/datamanager/lib/python2.7/site-packages/sqlalchemy/dialects/postgresql/json.pyt   contained_by_  s    (
   R'   R(   R)   R0   R4   RL   RM   RN   RP   RQ   (    (    (    si   /var/www/send.findwatt.com/datamanager/lib/python2.7/site-packages/sqlalchemy/dialects/postgresql/json.pyR-   6  s   						(
   R'   R(   R)   RI   R*   t   hashableR$   R2   R3   R-   (    (    (    si   /var/www/send.findwatt.com/datamanager/lib/python2.7/site-packages/sqlalchemy/dialects/postgresql/json.pyR	   ο   s   Bt   jsonb(   s   JSONs   JSONElements   JSONB(   t
   __future__R    R>   t   baseR   t    R   R$   t   sql.operatorsR   R   R   R   t   __all__t   BinaryExpressionR   t
   TypeEngineR   R	   (    (    (    si   /var/www/send.findwatt.com/datamanager/lib/python2.7/site-packages/sqlalchemy/dialects/postgresql/json.pyt   <module>   s   L
v