Statistics
| Branch: | Tag: | Revision:

root / snf-pithos-backend / pithos / backends / lib / sqlite / xfeatures.py @ 3759eddb

History | View | Annotate | Download (6.3 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 collections import defaultdict
35

    
36
from dbworker import DBWorker
37

    
38

    
39
class XFeatures(DBWorker):
40
    """XFeatures are path properties that allow non-nested
41
       inheritance patterns. Currently used for storing permissions.
42
    """
43

    
44
    def __init__(self, **params):
45
        DBWorker.__init__(self, **params)
46
        execute = self.execute
47

    
48
        execute(""" pragma foreign_keys = on """)
49

    
50
        execute(""" create table if not exists xfeatures
51
                          ( feature_id integer primary key,
52
                            path       text ) """)
53
        execute(""" create unique index if not exists idx_features_path
54
                    on xfeatures(path) """)
55

    
56
        execute(""" create table if not exists xfeaturevals
57
                          ( feature_id integer,
58
                            key        integer,
59
                            value      text,
60
                            primary key (feature_id, key, value)
61
                            foreign key (feature_id) references
62
                                xfeatures(feature_id)
63
                            on delete cascade ) """)
64

    
65
#     def xfeature_inherit(self, path):
66
#         """Return the (path, feature) inherited by the path, or None."""
67
#
68
#         q = ("select path, feature_id from xfeatures "
69
#              "where path <= ? "
70
#              "and ? like path || '%' " # XXX: Escape like...
71
#              "order by path desc")
72
#         self.execute(q, (path, path))
73
#         return self.fetchall()
74

    
75
    def xfeature_get(self, path):
76
        """Return feature for path."""
77

    
78
        q = "select feature_id from xfeatures where path = ?"
79
        self.execute(q, (path,))
80
        r = self.fetchone()
81
        if r is not None:
82
            return r[0]
83
        return None
84

    
85
    def xfeature_get_bulk(self, paths):
86
        """Return features for paths."""
87

    
88
        paths = list(set(paths))
89
        q = ("select feature_id, path from xfeatures "
90
             "where path in (%s) "
91
             "order by path") % ','.join('?' for _ in paths)
92
        self.execute(q, paths)
93
        rows = self.fetchall()
94
        if rows:
95
            return rows
96
        return None
97

    
98
    def xfeature_create(self, path):
99
        """Create and return a feature for path.
100
           If the path has a feature, return it.
101
        """
102

    
103
        feature = self.xfeature_get(path)
104
        if feature is not None:
105
            return feature
106
        q = "insert into xfeatures (path) values (?)"
107
        id = self.execute(q, (path,)).lastrowid
108
        return id
109

    
110
    def xfeature_destroy(self, path):
111
        """Destroy a feature and all its key, value pairs."""
112

    
113
        q = "delete from xfeatures where path = ?"
114
        self.execute(q, (path,))
115

    
116
    def xfeature_destroy_bulk(self, paths):
117
        """Destroy features and all their key, value pairs."""
118

    
119
        placeholders = ','.join('?' for path in paths)
120
        q = "delete from xfeatures where path in (%s)" % placeholders
121
        self.execute(q, paths)
122

    
123
    def feature_dict(self, feature):
124
        """Return a dict mapping keys to list of values for feature."""
125

    
126
        q = "select key, value from xfeaturevals where feature_id = ?"
127
        self.execute(q, (feature,))
128
        d = defaultdict(list)
129
        for key, value in self.fetchall():
130
            d[key].append(value)
131
        return d
132

    
133
    def feature_set(self, feature, key, value):
134
        """Associate a key, value pair with a feature."""
135

    
136
        q = ("insert or ignore into xfeaturevals (feature_id, key, value) "
137
             "values (?, ?, ?)")
138
        self.execute(q, (feature, key, value))
139

    
140
    def feature_setmany(self, feature, key, values):
141
        """Associate the given key, and values with a feature."""
142

    
143
        q = ("insert or ignore into xfeaturevals (feature_id, key, value) "
144
             "values (?, ?, ?)")
145
        self.executemany(q, ((feature, key, v) for v in values))
146

    
147
    def feature_unset(self, feature, key, value):
148
        """Disassociate a key, value pair from a feature."""
149

    
150
        q = ("delete from xfeaturevals where "
151
             "feature_id = ? and key = ? and value = ?")
152
        self.execute(q, (feature, key, value))
153

    
154
    def feature_unsetmany(self, feature, key, values):
155
        """Disassociate the key for the values given, from a feature."""
156

    
157
        q = ("delete from xfeaturevals where "
158
             "feature_id = ? and key = ? and value = ?")
159
        self.executemany(q, ((feature, key, v) for v in values))
160

    
161
    def feature_get(self, feature, key):
162
        """Return the list of values for a key of a feature."""
163

    
164
        q = "select value from xfeaturevals where feature_id = ? and key = ?"
165
        self.execute(q, (feature, key))
166
        return [r[0] for r in self.fetchall()]
167

    
168
    def feature_clear(self, feature, key):
169
        """Delete all key, value pairs for a key of a feature."""
170

    
171
        q = "delete from xfeaturevals where feature_id = ? and key = ?"
172
        self.execute(q, (feature, key))