ó
½-'Nc           @   s   d  Z  d d l Z y d d l Z Wn! e k
 rE d d l m Z n Xd d l m Z d d l m	 Z	 d e
 f d „  ƒ  YZ d e
 f d	 „  ƒ  YZ d
 e f d „  ƒ  YZ d e f d „  ƒ  YZ d e f d „  ƒ  YZ d e f d „  ƒ  YZ d „  Z d „  Z d S(   sE   Provide access to the persistent data used by L{PackageTaskHandler}s.iÿÿÿÿN(   t   dbapi2(   t   bpickle(   t   with_cursort   UnknownHashIDRequestc           B   s   e  Z d  Z RS(   s$   Raised for unknown hash id requests.(   t   __name__t
   __module__t   __doc__(    (    (    s;   /usr/lib/python2.7/dist-packages/landscape/package/store.pyR      s   t   InvalidHashIdDbc           B   s   e  Z d  Z RS(   sA   Raised when trying to add an invalid hash=>id lookaside database.(   R   R   R   (    (    (    s;   /usr/lib/python2.7/dist-packages/landscape/package/store.pyR      s   t   HashIdStorec           B   s€   e  Z d  Z d	 Z d „  Z d „  Z e d „  ƒ Z e d „  ƒ Z	 e d „  ƒ Z
 e d „  ƒ Z e d „  ƒ Z e d „  ƒ Z RS(
   sÈ   Persist package hash=>id mappings in a file.

    The implementation uses a SQLite database as backend, with a single
    table called "hash", whose schema is defined in L{ensure_hash_id_schema}.
    c         C   s   | |  _  d S(   sP   
        @param filename: The file where the mappings are persisted to.
        N(   t	   _filename(   t   selft   filename(    (    s;   /usr/lib/python2.7/dist-packages/landscape/package/store.pyt   __init__   s    c         C   s   t  |  j ƒ d  S(   N(   t   ensure_hash_id_schemat   _db(   R
   (    (    s;   /usr/lib/python2.7/dist-packages/landscape/package/store.pyt   _ensure_schema#   s    c         C   s=   x6 | j  ƒ  D]( \ } } | j d | t | ƒ f ƒ q Wd S(   sb   Set the ids of a set of hashes.

        @param hash_ids: a C{dict} of hash=>id mappings.
        s   REPLACE INTO hash VALUES (?, ?)N(   t	   iteritemst   executet   buffer(   R
   t   cursort   hash_idst   hasht   id(    (    s;   /usr/lib/python2.7/dist-packages/landscape/package/store.pyt   set_hash_ids&   s    	c         C   s7   | j  d t | ƒ f ƒ | j ƒ  } | r3 | d Sd S(   sA   Return the id associated to C{hash}, or C{None} if not available.s    SELECT id FROM hash WHERE hash=?i    N(   R   R   t   fetchonet   None(   R
   R   R   t   value(    (    s;   /usr/lib/python2.7/dist-packages/landscape/package/store.pyt   get_hash_id0   s
    c         C   sD   | j  d ƒ t g  | j ƒ  D]  } t | d ƒ | d f ^ q ƒ S(   s=   Return a C{dict} holding all the available hash=>id mappings.s   SELECT hash, id FROM hashi    i   (   R   t   dictt   fetchallt   str(   R
   R   t   row(    (    s;   /usr/lib/python2.7/dist-packages/landscape/package/store.pyt   get_hash_ids9   s    c         C   sR   t  | t t f ƒ s t ‚ | j d | f ƒ | j ƒ  } | rN t | d ƒ Sd S(   sA   Return the hash associated to C{id}, or C{None} if not available.s    SELECT hash FROM hash WHERE id=?i    N(   t
   isinstancet   intt   longt   AssertionErrorR   R   R   R   (   R
   R   R   R   (    (    s;   /usr/lib/python2.7/dist-packages/landscape/package/store.pyt   get_id_hash?   s    c         C   s   | j  d ƒ d S(   s   Delete all hash=>id mappings.s   DELETE FROM hashN(   R   (   R
   R   (    (    s;   /usr/lib/python2.7/dist-packages/landscape/package/store.pyt   clear_hash_idsI   s    c         C   s>   y | j  d d ƒ Wn# t j k
 r9 t |  j ƒ ‚ n Xd S(   sá   Check database integrity.

        @raise: L{InvalidHashIdDb} if the filenme passed to the constructor is
            not a SQLite database or does not have a table called "hash" with
            a compatible schema.
        s    SELECT id FROM hash WHERE hash=?t    N(   R'   (   R   t   sqlite3t   DatabaseErrorR   R	   (   R
   R   (    (    s;   /usr/lib/python2.7/dist-packages/landscape/package/store.pyt   check_sanityN   s    N(   R   R   R   R   R   R   R   R   R   R   R    R%   R&   R*   (    (    (    s;   /usr/lib/python2.7/dist-packages/landscape/package/store.pyR      s   		
	
t   PackageStorec           B   sÜ  e  Z d  Z d „  Z d „  Z d „  Z d „  Z d „  Z d „  Z e	 d „  ƒ Z
 e	 d „  ƒ Z e	 d	 „  ƒ Z e	 d
 „  ƒ Z e	 d „  ƒ Z e	 d „  ƒ Z e	 d „  ƒ Z e	 d „  ƒ Z e	 d „  ƒ Z e	 d „  ƒ Z e	 d „  ƒ Z e	 d „  ƒ Z e	 d „  ƒ Z e	 d „  ƒ Z e	 d „  ƒ Z e	 d „  ƒ Z e	 d „  ƒ Z e	 d „  ƒ Z e	 d „  ƒ Z e	 d „  ƒ Z e	 d „  ƒ Z e	 d „  ƒ Z e	 d „  ƒ Z  e	 d „  ƒ Z! e	 d „  ƒ Z" e	 d  „  ƒ Z# e	 d" d! „ ƒ Z$ RS(#   sx  Persist data about system packages and L{PackageTaskHandler}'s tasks.

    This class extends L{HashIdStore} by adding tables to the SQLite database
    backend for storing information about the status of the system packages and
    about the tasks to be performed by L{PackageTaskHandler}s.

    The additional tables and schemas are defined in L{ensure_package_schema}.
    c         C   s#   t  t |  ƒ j | ƒ g  |  _ d S(   sG   
        @param filename: The file where data is persisted to.
        N(   t   superR+   R   t   _hash_id_stores(   R
   R   (    (    s;   /usr/lib/python2.7/dist-packages/landscape/package/store.pyR   f   s    c         C   s$   t  t |  ƒ j ƒ  t |  j ƒ d  S(   N(   R,   R+   R   t   ensure_package_schemaR   (   R
   (    (    s;   /usr/lib/python2.7/dist-packages/landscape/package/store.pyR   m   s    c         C   sJ   t  | ƒ } y | j ƒ  Wn t k
 r5 } | ‚ n X|  j j | ƒ d S(   s   
        Attach an additional "lookaside" hash=>id database.

        This method can be called more than once to attach several
        hash=>id databases, which will be queried *before* the main
        database, in the same the order they were added.

        If C{filename} is not a SQLite database or does not have a
        table called "hash" with a compatible schema, L{InvalidHashIdDb}
        is raised.

        @param filename: a secondary SQLite databases to look for pre-canned
                         hash=>id mappings.
        N(   R   R*   R   R-   t   append(   R
   R   t   hash_id_storet   e(    (    s;   /usr/lib/python2.7/dist-packages/landscape/package/store.pyt   add_hash_id_dbq   s    
c         C   s   t  |  j ƒ d k S(   s?   Return C{True} if one or more lookaside databases are attached.i    (   t   lenR-   (   R
   (    (    s;   /usr/lib/python2.7/dist-packages/landscape/package/store.pyt   has_hash_id_dbŠ   s    c         C   sR   t  | t ƒ s t ‚ x* |  j D] } | j | ƒ } | r | Sq Wt j |  | ƒ S(   s	  Return the id associated to C{hash}, or C{None} if not available.

        This method composes the L{HashIdStore.get_hash_id} methods of all
        the attached lookaside databases, falling back to the main one, as
        described in L{add_hash_id_db}.
        (   R!   t
   basestringR$   R-   R   R   (   R
   R   t   storeR   (    (    s;   /usr/lib/python2.7/dist-packages/landscape/package/store.pyR   Ž   s    c         C   sC   x0 |  j  D]% } | j | ƒ } | d k	 r
 | Sq
 Wt j |  | ƒ S(   s'  Return the hash associated to C{id}, or C{None} if not available.

        This method composes the L{HashIdStore.get_id_hash} methods of all
        the attached lookaside databases, falling back to the main one in
        case the hash associated to C{id} is not found in any of them.
        N(   R-   R%   R   R   (   R
   R   R6   R   (    (    s;   /usr/lib/python2.7/dist-packages/landscape/package/store.pyR%       s
    c         C   s(   x! | D] } | j  d | f ƒ q Wd  S(   Ns!   REPLACE INTO available VALUES (?)(   R   (   R
   R   t   idsR   (    (    s;   /usr/lib/python2.7/dist-packages/landscape/package/store.pyt   add_available­   s    c         C   s.   d j  d „  | Dƒ ƒ } | j d | ƒ d  S(   Nt   ,c         s   s!   |  ] } t  t | ƒ ƒ Vq d  S(   N(   R   R"   (   t   .0R   (    (    s;   /usr/lib/python2.7/dist-packages/landscape/package/store.pys	   <genexpr>´   s    s&   DELETE FROM available WHERE id IN (%s)(   t   joinR   (   R
   R   R7   t   id_list(    (    s;   /usr/lib/python2.7/dist-packages/landscape/package/store.pyt   remove_available²   s    c         C   s   | j  d ƒ d  S(   Ns   DELETE FROM available(   R   (   R
   R   (    (    s;   /usr/lib/python2.7/dist-packages/landscape/package/store.pyt   clear_available·   s    c         C   s.   | j  d ƒ g  | j ƒ  D] } | d ^ q S(   Ns   SELECT id FROM availablei    (   R   R   (   R
   R   R   (    (    s;   /usr/lib/python2.7/dist-packages/landscape/package/store.pyt   get_available»   s    c         C   s(   x! | D] } | j  d | f ƒ q Wd  S(   Ns)   REPLACE INTO available_upgrade VALUES (?)(   R   (   R
   R   R7   R   (    (    s;   /usr/lib/python2.7/dist-packages/landscape/package/store.pyt   add_available_upgradesÀ   s    c         C   s.   d j  d „  | Dƒ ƒ } | j d | ƒ d  S(   NR9   c         s   s!   |  ] } t  t | ƒ ƒ Vq d  S(   N(   R   R"   (   R:   R   (    (    s;   /usr/lib/python2.7/dist-packages/landscape/package/store.pys	   <genexpr>Ç   s    s.   DELETE FROM available_upgrade WHERE id IN (%s)(   R;   R   (   R
   R   R7   R<   (    (    s;   /usr/lib/python2.7/dist-packages/landscape/package/store.pyt   remove_available_upgradesÅ   s    	c         C   s   | j  d ƒ d  S(   Ns   DELETE FROM available_upgrade(   R   (   R
   R   (    (    s;   /usr/lib/python2.7/dist-packages/landscape/package/store.pyt   clear_available_upgradesË   s    c         C   s.   | j  d ƒ g  | j ƒ  D] } | d ^ q S(   Ns    SELECT id FROM available_upgradei    (   R   R   (   R
   R   R   (    (    s;   /usr/lib/python2.7/dist-packages/landscape/package/store.pyt   get_available_upgradesÏ   s    c         C   s(   x! | D] } | j  d | f ƒ q Wd  S(   Ns!   REPLACE INTO installed VALUES (?)(   R   (   R
   R   R7   R   (    (    s;   /usr/lib/python2.7/dist-packages/landscape/package/store.pyt   add_installedÔ   s    c         C   s.   d j  d „  | Dƒ ƒ } | j d | ƒ d  S(   NR9   c         s   s!   |  ] } t  t | ƒ ƒ Vq d  S(   N(   R   R"   (   R:   R   (    (    s;   /usr/lib/python2.7/dist-packages/landscape/package/store.pys	   <genexpr>Û   s    s&   DELETE FROM installed WHERE id IN (%s)(   R;   R   (   R
   R   R7   R<   (    (    s;   /usr/lib/python2.7/dist-packages/landscape/package/store.pyt   remove_installedÙ   s    c         C   s   | j  d ƒ d  S(   Ns   DELETE FROM installed(   R   (   R
   R   (    (    s;   /usr/lib/python2.7/dist-packages/landscape/package/store.pyt   clear_installedÞ   s    c         C   s.   | j  d ƒ g  | j ƒ  D] } | d ^ q S(   Ns   SELECT id FROM installedi    (   R   R   (   R
   R   R   (    (    s;   /usr/lib/python2.7/dist-packages/landscape/package/store.pyt   get_installedâ   s    c         C   s.   | j  d ƒ g  | j ƒ  D] } | d ^ q S(   s+   Get the package ids of all locked packages.s   SELECT id FROM lockedi    (   R   R   (   R
   R   R   (    (    s;   /usr/lib/python2.7/dist-packages/landscape/package/store.pyt
   get_lockedç   s    c         C   s(   x! | D] } | j  d | f ƒ q Wd S(   s9   Add the given package ids to the list of locked packages.s   REPLACE INTO locked VALUES (?)N(   R   (   R
   R   R7   R   (    (    s;   /usr/lib/python2.7/dist-packages/landscape/package/store.pyt
   add_lockedí   s    c         C   s.   d j  d „  | Dƒ ƒ } | j d | ƒ d  S(   NR9   c         s   s!   |  ] } t  t | ƒ ƒ Vq d  S(   N(   R   R"   (   R:   R   (    (    s;   /usr/lib/python2.7/dist-packages/landscape/package/store.pys	   <genexpr>õ   s    s#   DELETE FROM locked WHERE id IN (%s)(   R;   R   (   R
   R   R7   R<   (    (    s;   /usr/lib/python2.7/dist-packages/landscape/package/store.pyt   remove_lockedó   s    c         C   s   | j  d ƒ d S(   s/   Remove all the package ids in the locked table.s   DELETE FROM lockedN(   R   (   R
   R   (    (    s;   /usr/lib/python2.7/dist-packages/landscape/package/store.pyt   clear_lockedø   s    c         C   s?   | j  d ƒ g  | j ƒ  D]! } | d | d | d f ^ q S(   s   Get all package locks.s1   SELECT name, relation, version FROM package_locksi    i   i   (   R   R   (   R
   R   R   (    (    s;   /usr/lib/python2.7/dist-packages/landscape/package/store.pyt   get_package_locksý   s    c         C   sC   x< | D]4 \ } } } | j  d | | p+ d | p4 d f ƒ q Wd S(   sË   Add a list of package locks to the store.

        @param locks: A C{list} of ternary tuples each one contains the
            name, the relation and the version of the package lock to be added.
        s+   REPLACE INTO package_locks VALUES (?, ?, ?)R'   N(   R   (   R
   R   t   lockst   namet   relationt   version(    (    s;   /usr/lib/python2.7/dist-packages/landscape/package/store.pyt   add_package_locks  s    	c         C   sC   x< | D]4 \ } } } | j  d | | p+ d | p4 d f ƒ q Wd S(   sÒ   Remove a list of package locks from the store.

        @param locks: A C{list} of ternary tuples each one contains the name,
            the relation and the version of the package lock to be removed.
        sC   DELETE FROM package_locks WHERE name=? AND relation=? AND version=?R'   N(   R   (   R
   R   RM   RN   RO   RP   (    (    s;   /usr/lib/python2.7/dist-packages/landscape/package/store.pyt   remove_package_locks  s    	c         C   s   | j  d ƒ d S(   s   Remove all package locks.s   DELETE FROM package_locksN(   R   (   R
   R   (    (    s;   /usr/lib/python2.7/dist-packages/landscape/package/store.pyt   clear_package_locks  s    c         C   sJ   t  | ƒ } | j d t t j | ƒ ƒ t j ƒ  f ƒ t |  j | j ƒ S(   Ns<   INSERT INTO hash_id_request (hashes, timestamp) VALUES (?,?)(	   t   listR   R   R   t   dumpst   timet   HashIDRequestR   t	   lastrowid(   R
   R   t   hashes(    (    s;   /usr/lib/python2.7/dist-packages/landscape/package/store.pyt   add_hash_id_request  s    	"c         C   s>   | j  d | f ƒ | j ƒ  s. t | ƒ ‚ n  t |  j | ƒ S(   Ns(   SELECT 1 FROM hash_id_request WHERE id=?(   R   R   R   RW   R   (   R
   R   t
   request_id(    (    s;   /usr/lib/python2.7/dist-packages/landscape/package/store.pyt   get_hash_id_request'  s
    	
c         C   s:   | j  d ƒ g  | j ƒ  D] } t |  j | d ƒ ^ q S(   Ns   SELECT id FROM hash_id_requesti    (   R   R   RW   R   (   R
   R   R   (    (    s;   /usr/lib/python2.7/dist-packages/landscape/package/store.pyt   iter_hash_id_requests/  s    c         C   s   | j  d ƒ d  S(   Ns   DELETE FROM hash_id_request(   R   (   R
   R   (    (    s;   /usr/lib/python2.7/dist-packages/landscape/package/store.pyt   clear_hash_id_requests4  s    c         C   sG   t  j | ƒ } | j d | t j ƒ  t | ƒ f ƒ t |  j | j ƒ S(   Ns8   INSERT INTO task (queue, timestamp, data) VALUES (?,?,?)(   R   RU   R   RV   R   t   PackageTaskR   RX   (   R
   R   t   queuet   data(    (    s;   /usr/lib/python2.7/dist-packages/landscape/package/store.pyt   add_task8  s    	c         C   s=   | j  d | f ƒ | j ƒ  } | r9 t |  j | d ƒ Sd  S(   Ns4   SELECT id FROM task WHERE queue=? ORDER BY timestampi    (   R   R   R_   R   R   (   R
   R   R`   R   (    (    s;   /usr/lib/python2.7/dist-packages/landscape/package/store.pyt   get_next_task?  s    	
c         C   s:   | j  d d j g  | D] } t | j ƒ ^ q ƒ ƒ d  S(   Ns%   DELETE FROM task WHERE id NOT IN (%s)R9   (   R   R;   R   R   (   R
   R   t   except_taskst   task(    (    s;   /usr/lib/python2.7/dist-packages/landscape/package/store.pyt   clear_tasksH  s    	(    (%   R   R   R   R   R   R2   R4   R   R%   R   R8   R=   R>   R?   R@   RA   RB   RC   RD   RE   RF   RG   RH   RI   RJ   RK   RL   RQ   RR   RS   RZ   R\   R]   R^   Rb   Rc   Rf   (    (    (    s;   /usr/lib/python2.7/dist-packages/landscape/package/store.pyR+   \   sF   							RW   c           B   s   e  Z d  „  Z e e d „  ƒ ƒ Z e d „  ƒ Z e d „  ƒ Z e e e ƒ Z e d „  ƒ Z	 e d „  ƒ Z
 e e	 e
 ƒ Z e d „  ƒ Z RS(   c         C   s   | |  _  | |  _ d  S(   N(   R   R   (   R
   t   dbR   (    (    s;   /usr/lib/python2.7/dist-packages/landscape/package/store.pyR   P  s    	c         C   s3   | j  d |  j f ƒ t j t | j ƒ  d ƒ ƒ S(   Ns-   SELECT hashes FROM hash_id_request WHERE id=?i    (   R   R   R   t   loadsR   R   (   R
   R   (    (    s;   /usr/lib/python2.7/dist-packages/landscape/package/store.pyRY   T  s    	c         C   s$   | j  d |  j f ƒ | j ƒ  d S(   Ns0   SELECT timestamp FROM hash_id_request WHERE id=?i    (   R   R   R   (   R
   R   (    (    s;   /usr/lib/python2.7/dist-packages/landscape/package/store.pyt   _get_timestamp[  s    	c         C   s   | j  d | |  j f ƒ d  S(   Ns1   UPDATE hash_id_request SET timestamp=? WHERE id=?(   R   R   (   R
   R   R   (    (    s;   /usr/lib/python2.7/dist-packages/landscape/package/store.pyt   _set_timestampa  s    	c         C   s$   | j  d |  j f ƒ | j ƒ  d S(   Ns1   SELECT message_id FROM hash_id_request WHERE id=?i    (   R   R   R   (   R
   R   (    (    s;   /usr/lib/python2.7/dist-packages/landscape/package/store.pyt   _get_message_idh  s    	c         C   s   | j  d | |  j f ƒ d  S(   Ns2   UPDATE hash_id_request SET message_id=? WHERE id=?(   R   R   (   R
   R   R   (    (    s;   /usr/lib/python2.7/dist-packages/landscape/package/store.pyt   _set_message_idn  s    	c         C   s   | j  d |  j f ƒ d  S(   Ns&   DELETE FROM hash_id_request WHERE id=?(   R   R   (   R
   R   (    (    s;   /usr/lib/python2.7/dist-packages/landscape/package/store.pyt   removeu  s    (   R   R   R   t   propertyR   RY   Ri   Rj   t	   timestampRk   Rl   t
   message_idRm   (    (    (    s;   /usr/lib/python2.7/dist-packages/landscape/package/store.pyRW   N  s   	R_   c           B   s    e  Z d  „  Z e d „  ƒ Z RS(   c         C   s‰   | |  _  | |  _ | j ƒ  } z# | j d | f ƒ | j ƒ  } Wd  | j ƒ  X| d |  _ | d |  _ t j	 t
 | d ƒ ƒ |  _ d  S(   Ns2   SELECT queue, timestamp, data FROM task WHERE id=?i    i   i   (   R   R   R   R   R   t   closeR`   Ro   R   Rh   R   Ra   (   R
   Rg   R   R   R   (    (    s;   /usr/lib/python2.7/dist-packages/landscape/package/store.pyR   |  s    			
c         C   s   | j  d |  j f ƒ d  S(   Ns   DELETE FROM task WHERE id=?(   R   R   (   R
   R   (    (    s;   /usr/lib/python2.7/dist-packages/landscape/package/store.pyRm   Œ  s    (   R   R   R   R   Rm   (    (    (    s;   /usr/lib/python2.7/dist-packages/landscape/package/store.pyR_   z  s   	c         C   si   |  j  ƒ  } y | j d ƒ Wn1 t j t j f k
 rP | j ƒ  |  j ƒ  n X| j ƒ  |  j ƒ  d S(   se   Create all tables needed by a L{HashIdStore}.

    @param db: A connection to a SQLite database.
    s<   CREATE TABLE hash (id INTEGER PRIMARY KEY, hash BLOB UNIQUE)N(   R   R   R(   t   OperationalErrorR)   Rq   t   rollbackt   commit(   Rg   R   (    (    s;   /usr/lib/python2.7/dist-packages/landscape/package/store.pyR   ‘  s    

c         C   s®   |  j  ƒ  } y_ | j d ƒ | j d ƒ | j d ƒ | j d ƒ | j d ƒ | j d ƒ | j d ƒ Wn( t j k
 r• | j ƒ  |  j ƒ  n X| j ƒ  |  j ƒ  d S(	   sf   Create all tables needed by a L{PackageStore}.

    @param db: A connection to a SQLite database.
    sm   CREATE TABLE package_locks (name TEXT NOT NULL, relation TEXT, version TEXT, UNIQUE(name, relation, version))s,   CREATE TABLE locked (id INTEGER PRIMARY KEY)s/   CREATE TABLE available (id INTEGER PRIMARY KEY)s7   CREATE TABLE available_upgrade (id INTEGER PRIMARY KEY)s/   CREATE TABLE installed (id INTEGER PRIMARY KEY)sk   CREATE TABLE hash_id_request (id INTEGER PRIMARY KEY, timestamp TIMESTAMP, message_id INTEGER, hashes BLOB)sV   CREATE TABLE task (id INTEGER PRIMARY KEY, queue TEXT, timestamp TIMESTAMP, data BLOB)N(   R   R   R(   Rr   Rq   Rs   Rt   (   Rg   R   (    (    s;   /usr/lib/python2.7/dist-packages/landscape/package/store.pyR.   ¢  s    	

(   R   RV   R(   t   ImportErrort	   pysqlite2R    t   landscape.libR   t   landscape.lib.storeR   t	   ExceptionR   R   t   objectR   R+   RW   R_   R   R.   (    (    (    s;   /usr/lib/python2.7/dist-packages/landscape/package/store.pyt   <module>   s   Gò,	