Statistics
| Branch: | Tag: | Revision:

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

History | View | Annotate | Download (5.9 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_create(self, path):
86
        """Create and return a feature for path.
87
           If the path has a feature, return it.
88
        """
89

    
90
        feature = self.xfeature_get(path)
91
        if feature is not None:
92
            return feature
93
        q = "insert into xfeatures (path) values (?)"
94
        id = self.execute(q, (path,)).lastrowid
95
        return id
96

    
97
    def xfeature_destroy(self, path):
98
        """Destroy a feature and all its key, value pairs."""
99

    
100
        q = "delete from xfeatures where path = ?"
101
        self.execute(q, (path,))
102

    
103
    def xfeature_destroy_bulk(self, paths):
104
        """Destroy features and all their key, value pairs."""
105

    
106
        placeholders = ','.join('?' for path in paths)
107
        q = "delete from xfeatures where path in (%s)" % placeholders
108
        self.execute(q, paths)
109

    
110
    def feature_dict(self, feature):
111
        """Return a dict mapping keys to list of values for feature."""
112

    
113
        q = "select key, value from xfeaturevals where feature_id = ?"
114
        self.execute(q, (feature,))
115
        d = defaultdict(list)
116
        for key, value in self.fetchall():
117
            d[key].append(value)
118
        return d
119

    
120
    def feature_set(self, feature, key, value):
121
        """Associate a key, value pair with a feature."""
122

    
123
        q = ("insert or ignore into xfeaturevals (feature_id, key, value) "
124
             "values (?, ?, ?)")
125
        self.execute(q, (feature, key, value))
126

    
127
    def feature_setmany(self, feature, key, values):
128
        """Associate the given key, and values with a feature."""
129

    
130
        q = ("insert or ignore into xfeaturevals (feature_id, key, value) "
131
             "values (?, ?, ?)")
132
        self.executemany(q, ((feature, key, v) for v in values))
133

    
134
    def feature_unset(self, feature, key, value):
135
        """Disassociate a key, value pair from a feature."""
136

    
137
        q = ("delete from xfeaturevals where "
138
             "feature_id = ? and key = ? and value = ?")
139
        self.execute(q, (feature, key, value))
140

    
141
    def feature_unsetmany(self, feature, key, values):
142
        """Disassociate the key for the values given, from a feature."""
143

    
144
        q = ("delete from xfeaturevals where "
145
             "feature_id = ? and key = ? and value = ?")
146
        self.executemany(q, ((feature, key, v) for v in values))
147

    
148
    def feature_get(self, feature, key):
149
        """Return the list of values for a key of a feature."""
150

    
151
        q = "select value from xfeaturevals where feature_id = ? and key = ?"
152
        self.execute(q, (feature, key))
153
        return [r[0] for r in self.fetchall()]
154

    
155
    def feature_clear(self, feature, key):
156
        """Delete all key, value pairs for a key of a feature."""
157

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