Statistics
| Branch: | Tag: | Revision:

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

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

    
64

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

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

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

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

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

    
102
    def public_unset(self, path):
103
        s = self.public.delete()
104
        s = s.where(self.public.c.path == path)
105
        self.conn.execute(s).close()
106
        logger.info('Public url unset for path: %s' % (path))
107

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

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

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

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