Statistics
| Branch: | Tag: | Revision:

root / snf-pithos-backend / pithos / backends / lib / sqlalchemy / groups.py @ 6a82f89f

History | View | Annotate | Download (6 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
from sqlalchemy import Table, Column, String, MetaData
36
from sqlalchemy.sql import select, and_
37
from sqlalchemy.schema import Index
38
from sqlalchemy.exc import NoSuchTableError
39

    
40
from dbworker import DBWorker
41

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