Statistics
| Branch: | Tag: | Revision:

root / snf-pithos-backend / pithos / backends / lib / sqlalchemy / public.py @ dc7159be

History | View | Annotate | Download (5.2 kB)

1
# Copyright 2011-2012 GRNET S.A. All rights reserved.
2
#
3
# Redistribution and use in source and binary forms, with or
4
# without modification, are permitted provided that the following
5
# conditions are met:
6
#
7
#   1. Redistributions of source code must retain the above
8
#      copyright notice, this list of conditions and the following
9
#      disclaimer.
10
#
11
#   2. Redistributions in binary form must reproduce the above
12
#      copyright notice, this list of conditions and the following
13
#      disclaimer in the documentation and/or other materials
14
#      provided with the distribution.
15
#
16
# THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS
17
# OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR
20
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
23
# USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
24
# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
26
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27
# POSSIBILITY OF SUCH DAMAGE.
28
#
29
# The views and conclusions contained in the software and
30
# documentation are those of the authors and should not be
31
# interpreted as representing official policies, either expressed
32
# or implied, of GRNET S.A.
33

    
34
from dbworker import DBWorker
35
from sqlalchemy import Table, Column, String, Integer, Boolean, MetaData
36
from sqlalchemy.sql import and_, select
37
from sqlalchemy.schema import Index
38
from sqlalchemy.exc import NoSuchTableError
39

    
40
from pithos.backends.random_word import get_random_word
41

    
42
from dbworker import ESCAPE_CHAR
43

    
44
import logging
45

    
46
logger = logging.getLogger(__name__)
47

    
48

    
49
def create_tables(engine):
50
    metadata = MetaData()
51
    columns = []
52
    columns.append(Column('public_id', Integer, primary_key=True))
53
    columns.append(Column('path', String(2048), nullable=False))
54
    columns.append(Column('active', Boolean, nullable=False, default=True))
55
    columns.append(Column('url', String(2048), nullable=True))
56
    public = Table('public', metadata, *columns, mysql_engine='InnoDB',
57
                   sqlite_autoincrement=True)
58
    # place an index on path
59
    Index('idx_public_path', public.c.path, unique=True)
60
    # place an index on url
61
    Index('idx_public_url', public.c.url, unique=True)
62
    metadata.create_all(engine)
63
    return metadata.sorted_tables
64

    
65

    
66
class Public(DBWorker):
67
    """Paths can be marked as public."""
68

    
69
    def __init__(self, **params):
70
        DBWorker.__init__(self, **params)
71
        try:
72
            metadata = MetaData(self.engine)
73
            self.public = Table('public', metadata, autoload=True)
74
        except NoSuchTableError:
75
            tables = create_tables(self.engine)
76
            map(lambda t: self.__setattr__(t.name, t), tables)
77

    
78
    def get_unique_url(self, public_security, public_url_alphabet):
79
        l = public_security
80
        while 1:
81
            candidate = get_random_word(length=l, alphabet=public_url_alphabet)
82
            if self.public_path(candidate) is None:
83
                return candidate
84
            l += 1
85

    
86
    def public_set(self, path, public_security, public_url_alphabet):
87
        s = select([self.public.c.public_id])
88
        s = s.where(self.public.c.path == path)
89
        r = self.conn.execute(s)
90
        row = r.fetchone()
91
        r.close()
92

    
93
        if not row:
94
            url = self.get_unique_url(
95
                public_security, public_url_alphabet
96
            )
97
            s = self.public.insert()
98
            s = s.values(path=path, active=True, url=url)
99
            r = self.conn.execute(s)
100
            r.close()
101
            logger.info('Public url set for path: %s' % path)
102

    
103
    def public_unset(self, path):
104
        s = self.public.delete()
105
        s = s.where(self.public.c.path == path)
106
        r = self.conn.execute(s)
107
        if r.rowcount != 0:
108
            logger.info('Public url unset for path: %s' % path)
109
        r.close()
110

    
111
    def public_unset_bulk(self, paths):
112
        if not paths:
113
            return
114
        s = self.public.delete()
115
        s = s.where(self.public.c.path.in_(paths))
116
        self.conn.execute(s).close()
117

    
118
    def public_get(self, path):
119
        s = select([self.public.c.url])
120
        s = s.where(and_(self.public.c.path == path,
121
                         self.public.c.active == True))
122
        r = self.conn.execute(s)
123
        row = r.fetchone()
124
        r.close()
125
        if row:
126
            return row[0]
127
        return None
128

    
129
    def public_list(self, prefix):
130
        s = select([self.public.c.path, self.public.c.url])
131
        s = s.where(self.public.c.path.like(
132
            self.escape_like(prefix) + '%', escape=ESCAPE_CHAR))
133
        s = s.where(self.public.c.active == True)
134
        r = self.conn.execute(s)
135
        rows = r.fetchall()
136
        r.close()
137
        return rows
138

    
139
    def public_path(self, public):
140
        s = select([self.public.c.path])
141
        s = s.where(and_(self.public.c.url == public,
142
                         self.public.c.active == True))
143
        r = self.conn.execute(s)
144
        row = r.fetchone()
145
        r.close()
146
        if row:
147
            return row[0]
148
        return None