Revision d50ed8d4 snf-pithos-backend/pithos/backends/lib/sqlite/xfeatures.py
b/snf-pithos-backend/pithos/backends/lib/sqlite/xfeatures.py | ||
---|---|---|
1 | 1 |
# Copyright 2011-2012 GRNET S.A. All rights reserved. |
2 |
#
|
|
2 |
# |
|
3 | 3 |
# Redistribution and use in source and binary forms, with or |
4 | 4 |
# without modification, are permitted provided that the following |
5 | 5 |
# conditions are met: |
6 |
#
|
|
6 |
# |
|
7 | 7 |
# 1. Redistributions of source code must retain the above |
8 | 8 |
# copyright notice, this list of conditions and the following |
9 | 9 |
# disclaimer. |
10 |
#
|
|
10 |
# |
|
11 | 11 |
# 2. Redistributions in binary form must reproduce the above |
12 | 12 |
# copyright notice, this list of conditions and the following |
13 | 13 |
# disclaimer in the documentation and/or other materials |
14 | 14 |
# provided with the distribution. |
15 |
#
|
|
15 |
# |
|
16 | 16 |
# THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS |
17 | 17 |
# OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
18 | 18 |
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
... | ... | |
25 | 25 |
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN |
26 | 26 |
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
27 | 27 |
# POSSIBILITY OF SUCH DAMAGE. |
28 |
#
|
|
28 |
# |
|
29 | 29 |
# The views and conclusions contained in the software and |
30 | 30 |
# documentation are those of the authors and should not be |
31 | 31 |
# interpreted as representing official policies, either expressed |
... | ... | |
40 | 40 |
"""XFeatures are path properties that allow non-nested |
41 | 41 |
inheritance patterns. Currently used for storing permissions. |
42 | 42 |
""" |
43 |
|
|
43 |
|
|
44 | 44 |
def __init__(self, **params): |
45 | 45 |
DBWorker.__init__(self, **params) |
46 | 46 |
execute = self.execute |
47 |
|
|
47 |
|
|
48 | 48 |
execute(""" pragma foreign_keys = on """) |
49 |
|
|
49 |
|
|
50 | 50 |
execute(""" create table if not exists xfeatures |
51 | 51 |
( feature_id integer primary key, |
52 | 52 |
path text ) """) |
... | ... | |
60 | 60 |
primary key (feature_id, key, value) |
61 | 61 |
foreign key (feature_id) references xfeatures(feature_id) |
62 | 62 |
on delete cascade ) """) |
63 |
|
|
63 |
|
|
64 | 64 |
# def xfeature_inherit(self, path): |
65 | 65 |
# """Return the (path, feature) inherited by the path, or None.""" |
66 |
#
|
|
66 |
# |
|
67 | 67 |
# q = ("select path, feature_id from xfeatures " |
68 | 68 |
# "where path <= ? " |
69 | 69 |
# "and ? like path || '%' " # XXX: Escape like... |
70 | 70 |
# "order by path desc") |
71 | 71 |
# self.execute(q, (path, path)) |
72 | 72 |
# return self.fetchall() |
73 |
|
|
73 |
|
|
74 | 74 |
def xfeature_get(self, path): |
75 | 75 |
"""Return feature for path.""" |
76 |
|
|
76 |
|
|
77 | 77 |
q = "select feature_id from xfeatures where path = ?" |
78 | 78 |
self.execute(q, (path,)) |
79 | 79 |
r = self.fetchone() |
80 | 80 |
if r is not None: |
81 | 81 |
return r[0] |
82 | 82 |
return None |
83 |
|
|
83 |
|
|
84 | 84 |
def xfeature_create(self, path): |
85 | 85 |
"""Create and return a feature for path. |
86 | 86 |
If the path has a feature, return it. |
87 | 87 |
""" |
88 |
|
|
88 |
|
|
89 | 89 |
feature = self.xfeature_get(path) |
90 | 90 |
if feature is not None: |
91 | 91 |
return feature |
92 | 92 |
q = "insert into xfeatures (path) values (?)" |
93 | 93 |
id = self.execute(q, (path,)).lastrowid |
94 | 94 |
return id |
95 |
|
|
95 |
|
|
96 | 96 |
def xfeature_destroy(self, path): |
97 | 97 |
"""Destroy a feature and all its key, value pairs.""" |
98 |
|
|
98 |
|
|
99 | 99 |
q = "delete from xfeatures where path = ?" |
100 | 100 |
self.execute(q, (path,)) |
101 |
|
|
101 |
|
|
102 | 102 |
def xfeature_destroy_bulk(self, paths): |
103 | 103 |
"""Destroy features and all their key, value pairs.""" |
104 |
|
|
104 |
|
|
105 | 105 |
placeholders = ','.join('?' for path in paths) |
106 | 106 |
q = "delete from xfeatures where path in (%s)" % placeholders |
107 | 107 |
self.execute(q, paths) |
108 |
|
|
108 |
|
|
109 | 109 |
def feature_dict(self, feature): |
110 | 110 |
"""Return a dict mapping keys to list of values for feature.""" |
111 |
|
|
111 |
|
|
112 | 112 |
q = "select key, value from xfeaturevals where feature_id = ?" |
113 | 113 |
self.execute(q, (feature,)) |
114 | 114 |
d = defaultdict(list) |
115 | 115 |
for key, value in self.fetchall(): |
116 | 116 |
d[key].append(value) |
117 | 117 |
return d |
118 |
|
|
118 |
|
|
119 | 119 |
def feature_set(self, feature, key, value): |
120 | 120 |
"""Associate a key, value pair with a feature.""" |
121 |
|
|
121 |
|
|
122 | 122 |
q = "insert or ignore into xfeaturevals (feature_id, key, value) values (?, ?, ?)" |
123 | 123 |
self.execute(q, (feature, key, value)) |
124 |
|
|
124 |
|
|
125 | 125 |
def feature_setmany(self, feature, key, values): |
126 | 126 |
"""Associate the given key, and values with a feature.""" |
127 |
|
|
127 |
|
|
128 | 128 |
q = "insert or ignore into xfeaturevals (feature_id, key, value) values (?, ?, ?)" |
129 | 129 |
self.executemany(q, ((feature, key, v) for v in values)) |
130 |
|
|
130 |
|
|
131 | 131 |
def feature_unset(self, feature, key, value): |
132 | 132 |
"""Disassociate a key, value pair from a feature.""" |
133 |
|
|
133 |
|
|
134 | 134 |
q = ("delete from xfeaturevals where " |
135 | 135 |
"feature_id = ? and key = ? and value = ?") |
136 | 136 |
self.execute(q, (feature, key, value)) |
137 |
|
|
137 |
|
|
138 | 138 |
def feature_unsetmany(self, feature, key, values): |
139 | 139 |
"""Disassociate the key for the values given, from a feature.""" |
140 |
|
|
140 |
|
|
141 | 141 |
q = ("delete from xfeaturevals where " |
142 | 142 |
"feature_id = ? and key = ? and value = ?") |
143 | 143 |
self.executemany(q, ((feature, key, v) for v in values)) |
144 |
|
|
144 |
|
|
145 | 145 |
def feature_get(self, feature, key): |
146 | 146 |
"""Return the list of values for a key of a feature.""" |
147 |
|
|
147 |
|
|
148 | 148 |
q = "select value from xfeaturevals where feature_id = ? and key = ?" |
149 | 149 |
self.execute(q, (feature, key)) |
150 | 150 |
return [r[0] for r in self.fetchall()] |
151 |
|
|
151 |
|
|
152 | 152 |
def feature_clear(self, feature, key): |
153 | 153 |
"""Delete all key, value pairs for a key of a feature.""" |
154 |
|
|
154 |
|
|
155 | 155 |
q = "delete from xfeaturevals where feature_id = ? and key = ?" |
156 | 156 |
self.execute(q, (feature, key)) |
Also available in: Unified diff