e7b1c364bc835fbdf6464897e3c1d53331f05953
[pithos] / pithos / backends / lib / sqlalchemy / groups.py
1 # Copyright 2011 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 from sqlalchemy import Table, Column, String, MetaData
36 from sqlalchemy.sql import select, and_
37 from sqlalchemy.schema import Index
38 from dbworker import DBWorker
39
40 class Groups(DBWorker):
41     """Groups are named collections of members, belonging to an owner."""
42     
43     def __init__(self, **params):
44         DBWorker.__init__(self, **params)
45         metadata = MetaData()
46         columns=[]
47         columns.append(Column('owner', String(255), primary_key=True))
48         columns.append(Column('name', String(255), primary_key=True))
49         columns.append(Column('member', String(255), primary_key=True))
50         self.groups = Table('groups', metadata, *columns, mysql_engine='InnoDB', mysql_charset='utf8')
51         
52         # place an index on member
53         Index('idx_groups_member', self.groups.c.member)
54         
55         metadata.create_all(self.engine)
56     
57     def group_names(self, owner):
58         """List all group names belonging to owner."""
59         
60         s = select([self.groups.c.name],
61             self.groups.c.owner==owner).distinct()
62         r = self.conn.execute(s)
63         l = [row[0] for row in r.fetchall()]
64         r.close()
65         return l
66     
67     def group_dict(self, owner):
68         """Return a dict mapping group names to member lists for owner."""
69         
70         s = select([self.groups.c.name, self.groups.c.member],
71             self.groups.c.owner==owner)
72         r = self.conn.execute(s)
73         d = defaultdict(list)
74         for group, member in r.fetchall():
75             d[group].append(member)
76         r.close()
77         return d
78     
79     def group_add(self, owner, group, member):
80         """Add a member to a group."""
81         
82         s = self.groups.select()
83         s = s.where(self.groups.c.owner == owner)
84         s = s.where(self.groups.c.name == group)
85         s = s.where(self.groups.c.member == member)
86         r = self.conn.execute(s)
87         groups = r.fetchall()
88         r.close()
89         if len(groups) == 0:    
90             s = self.groups.insert()
91             r = self.conn.execute(s, owner=owner, name=group, member=member)
92             r.close()
93     
94     def group_addmany(self, owner, group, members):
95         """Add members to a group."""
96         
97         #TODO: more efficient way to do it
98         for member in members:
99             self.group_add(owner, group, member)
100     
101     def group_remove(self, owner, group, member):
102         """Remove a member from a group."""
103         
104         s = self.groups.delete().where(and_(self.groups.c.owner==owner,
105                                             self.groups.c.name==group,
106                                             self.groups.c.member==member))
107         r = self.conn.execute(s)
108         r.close()
109     
110     def group_delete(self, owner, group):
111         """Delete a group."""
112         
113         s = self.groups.delete().where(and_(self.groups.c.owner==owner,
114                                             self.groups.c.name==group))
115         r = self.conn.execute(s)
116         r.close()
117     
118     def group_destroy(self, owner):
119         """Delete all groups belonging to owner."""
120         
121         s = self.groups.delete().where(self.groups.c.owner==owner)
122         r = self.conn.execute(s)
123         r.close()
124     
125     def group_members(self, owner, group):
126         """Return the list of members of a group."""
127         
128         s = select([self.groups.c.member], and_(self.groups.c.owner==owner,
129                                                 self.groups.c.name==group))
130         r = self.conn.execute(s)
131         l = [row[0] for row in r.fetchall()]
132         r.close()
133         return l
134     
135     def group_check(self, owner, group, member):
136         """Check if a member is in a group."""
137         
138         s = select([self.groups.c.member], and_(self.groups.c.owner==owner,
139                            self.groups.c.name==group,
140                            self.groups.c.member==member))
141         r = self.conn.execute(s)
142         l = r.fetchone()
143         r.close()
144         return bool(l)
145     
146     def group_parents(self, member):
147         """Return all (owner, group) tuples that contain member."""
148         
149         s = select([self.groups.c.owner, self.groups.c.name],
150             self.groups.c.member==member)
151         r = self.conn.execute(s)
152         l = r.fetchall()
153         r.close()
154         return l