Statistics
| Branch: | Tag: | Revision:

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

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

    
43
def create_tables(engine):
44
    metadata = MetaData()
45
    columns = []
46
    columns.append(Column('owner', String(256), primary_key=True))
47
    columns.append(Column('name', String(256), primary_key=True))
48
    columns.append(Column('member', String(256), primary_key=True))
49
    groups = Table('groups', metadata, *columns, mysql_engine='InnoDB')
50

    
51
    # place an index on member
52
    Index('idx_groups_member', groups.c.member)
53

    
54
    metadata.create_all(engine)
55
    return metadata.sorted_tables
56

    
57

    
58
class Groups(DBWorker):
59
    """Groups are named collections of members, belonging to an owner."""
60

    
61
    def __init__(self, **params):
62
        DBWorker.__init__(self, **params)
63
        try:
64
            metadata = MetaData(self.engine)
65
            self.groups = Table('groups', metadata, autoload=True)
66
        except NoSuchTableError:
67
            tables = create_tables(self.engine)
68
            map(lambda t: self.__setattr__(t.name, t), tables)
69

    
70
    def group_names(self, owner):
71
        """List all group names belonging to owner."""
72

    
73
        s = select([self.groups.c.name],
74
                   self.groups.c.owner == owner).distinct()
75
        r = self.conn.execute(s)
76
        l = [row[0] for row in r.fetchall()]
77
        r.close()
78
        return l
79

    
80
    def group_dict(self, owner):
81
        """Return a dict mapping group names to member lists for owner."""
82

    
83
        s = select([self.groups.c.name, self.groups.c.member],
84
                   self.groups.c.owner == owner)
85
        r = self.conn.execute(s)
86
        d = defaultdict(list)
87
        for group, member in r.fetchall():
88
            d[group].append(member)
89
        r.close()
90
        return d
91

    
92
    def group_add(self, owner, group, member):
93
        """Add a member to a group."""
94

    
95
        s = self.groups.select()
96
        s = s.where(self.groups.c.owner == owner)
97
        s = s.where(self.groups.c.name == group)
98
        s = s.where(self.groups.c.member == member)
99
        r = self.conn.execute(s)
100
        groups = r.fetchall()
101
        r.close()
102
        if len(groups) == 0:
103
            s = self.groups.insert()
104
            r = self.conn.execute(s, owner=owner, name=group, member=member)
105
            r.close()
106

    
107
    def group_addmany(self, owner, group, members):
108
        """Add members to a group."""
109

    
110
        #TODO: more efficient way to do it
111
        for member in members:
112
            self.group_add(owner, group, member)
113

    
114
    def group_remove(self, owner, group, member):
115
        """Remove a member from a group."""
116

    
117
        s = self.groups.delete().where(and_(self.groups.c.owner == owner,
118
                                            self.groups.c.name == group,
119
                                            self.groups.c.member == member))
120
        r = self.conn.execute(s)
121
        r.close()
122

    
123
    def group_delete(self, owner, group):
124
        """Delete a group."""
125

    
126
        s = self.groups.delete().where(and_(self.groups.c.owner == owner,
127
                                            self.groups.c.name == group))
128
        r = self.conn.execute(s)
129
        r.close()
130

    
131
    def group_destroy(self, owner):
132
        """Delete all groups belonging to owner."""
133

    
134
        s = self.groups.delete().where(self.groups.c.owner == owner)
135
        r = self.conn.execute(s)
136
        r.close()
137

    
138
    def group_members(self, owner, group):
139
        """Return the list of members of a group."""
140

    
141
        s = select([self.groups.c.member], and_(self.groups.c.owner == owner,
142
                                                self.groups.c.name == group))
143
        r = self.conn.execute(s)
144
        l = [row[0] for row in r.fetchall()]
145
        r.close()
146
        return l
147

    
148
    def group_check(self, owner, group, member):
149
        """Check if a member is in a group."""
150

    
151
        s = select([self.groups.c.member],
152
                   and_(self.groups.c.owner == owner,
153
                        self.groups.c.name == group,
154
                        self.groups.c.member == member))
155
        r = self.conn.execute(s)
156
        l = r.fetchone()
157
        r.close()
158
        return bool(l)
159

    
160
    def group_parents(self, member):
161
        """Return all (owner, group) tuples that contain member."""
162

    
163
        s = select([self.groups.c.owner, self.groups.c.name],
164
                   self.groups.c.member == member)
165
        r = self.conn.execute(s)
166
        l = r.fetchall()
167
        r.close()
168
        return l