##// END OF EJS Templates
fixed a bug in cache invalidation
marcink -
r1427:ba697e2f beta
parent child Browse files
Show More
@@ -1,800 +1,800 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2 """
2 """
3 rhodecode.model.db
3 rhodecode.model.db
4 ~~~~~~~~~~~~~~~~~~
4 ~~~~~~~~~~~~~~~~~~
5
5
6 Database Models for RhodeCode
6 Database Models for RhodeCode
7
7
8 :created_on: Apr 08, 2010
8 :created_on: Apr 08, 2010
9 :author: marcink
9 :author: marcink
10 :copyright: (C) 2009-2011 Marcin Kuzminski <marcin@python-works.com>
10 :copyright: (C) 2009-2011 Marcin Kuzminski <marcin@python-works.com>
11 :license: GPLv3, see COPYING for more details.
11 :license: GPLv3, see COPYING for more details.
12 """
12 """
13 # This program is free software: you can redistribute it and/or modify
13 # This program is free software: you can redistribute it and/or modify
14 # it under the terms of the GNU General Public License as published by
14 # it under the terms of the GNU General Public License as published by
15 # the Free Software Foundation, either version 3 of the License, or
15 # the Free Software Foundation, either version 3 of the License, or
16 # (at your option) any later version.
16 # (at your option) any later version.
17 #
17 #
18 # This program is distributed in the hope that it will be useful,
18 # This program is distributed in the hope that it will be useful,
19 # but WITHOUT ANY WARRANTY; without even the implied warranty of
19 # but WITHOUT ANY WARRANTY; without even the implied warranty of
20 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 # GNU General Public License for more details.
21 # GNU General Public License for more details.
22 #
22 #
23 # You should have received a copy of the GNU General Public License
23 # You should have received a copy of the GNU General Public License
24 # along with this program. If not, see <http://www.gnu.org/licenses/>.
24 # along with this program. If not, see <http://www.gnu.org/licenses/>.
25
25
26 import os
26 import os
27 import logging
27 import logging
28 import datetime
28 import datetime
29 import traceback
29 import traceback
30 from datetime import date
30 from datetime import date
31
31
32 from sqlalchemy import *
32 from sqlalchemy import *
33 from sqlalchemy.exc import DatabaseError
33 from sqlalchemy.exc import DatabaseError
34 from sqlalchemy.orm import relationship, backref, joinedload, class_mapper
34 from sqlalchemy.orm import relationship, backref, joinedload, class_mapper
35 from sqlalchemy.orm.interfaces import MapperExtension
35 from sqlalchemy.orm.interfaces import MapperExtension
36
36
37 from beaker.cache import cache_region, region_invalidate
37 from beaker.cache import cache_region, region_invalidate
38
38
39 from vcs import get_backend
39 from vcs import get_backend
40 from vcs.utils.helpers import get_scm
40 from vcs.utils.helpers import get_scm
41 from vcs.exceptions import RepositoryError, VCSError
41 from vcs.exceptions import RepositoryError, VCSError
42 from vcs.utils.lazy import LazyProperty
42 from vcs.utils.lazy import LazyProperty
43 from vcs.nodes import FileNode
43 from vcs.nodes import FileNode
44
44
45 from rhodecode.lib import str2bool, json, safe_str
45 from rhodecode.lib import str2bool, json, safe_str
46 from rhodecode.model.meta import Base, Session
46 from rhodecode.model.meta import Base, Session
47 from rhodecode.model.caching_query import FromCache
47 from rhodecode.model.caching_query import FromCache
48
48
49 log = logging.getLogger(__name__)
49 log = logging.getLogger(__name__)
50
50
51 #==============================================================================
51 #==============================================================================
52 # BASE CLASSES
52 # BASE CLASSES
53 #==============================================================================
53 #==============================================================================
54
54
55 class ModelSerializer(json.JSONEncoder):
55 class ModelSerializer(json.JSONEncoder):
56 """
56 """
57 Simple Serializer for JSON,
57 Simple Serializer for JSON,
58
58
59 usage::
59 usage::
60
60
61 to make object customized for serialization implement a __json__
61 to make object customized for serialization implement a __json__
62 method that will return a dict for serialization into json
62 method that will return a dict for serialization into json
63
63
64 example::
64 example::
65
65
66 class Task(object):
66 class Task(object):
67
67
68 def __init__(self, name, value):
68 def __init__(self, name, value):
69 self.name = name
69 self.name = name
70 self.value = value
70 self.value = value
71
71
72 def __json__(self):
72 def __json__(self):
73 return dict(name=self.name,
73 return dict(name=self.name,
74 value=self.value)
74 value=self.value)
75
75
76 """
76 """
77
77
78 def default(self, obj):
78 def default(self, obj):
79
79
80 if hasattr(obj, '__json__'):
80 if hasattr(obj, '__json__'):
81 return obj.__json__()
81 return obj.__json__()
82 else:
82 else:
83 return json.JSONEncoder.default(self, obj)
83 return json.JSONEncoder.default(self, obj)
84
84
85 class BaseModel(object):
85 class BaseModel(object):
86 """Base Model for all classess
86 """Base Model for all classess
87
87
88 """
88 """
89
89
90 @classmethod
90 @classmethod
91 def _get_keys(cls):
91 def _get_keys(cls):
92 """return column names for this model """
92 """return column names for this model """
93 return class_mapper(cls).c.keys()
93 return class_mapper(cls).c.keys()
94
94
95 def get_dict(self):
95 def get_dict(self):
96 """return dict with keys and values corresponding
96 """return dict with keys and values corresponding
97 to this model data """
97 to this model data """
98
98
99 d = {}
99 d = {}
100 for k in self._get_keys():
100 for k in self._get_keys():
101 d[k] = getattr(self, k)
101 d[k] = getattr(self, k)
102 return d
102 return d
103
103
104 def get_appstruct(self):
104 def get_appstruct(self):
105 """return list with keys and values tupples corresponding
105 """return list with keys and values tupples corresponding
106 to this model data """
106 to this model data """
107
107
108 l = []
108 l = []
109 for k in self._get_keys():
109 for k in self._get_keys():
110 l.append((k, getattr(self, k),))
110 l.append((k, getattr(self, k),))
111 return l
111 return l
112
112
113 def populate_obj(self, populate_dict):
113 def populate_obj(self, populate_dict):
114 """populate model with data from given populate_dict"""
114 """populate model with data from given populate_dict"""
115
115
116 for k in self._get_keys():
116 for k in self._get_keys():
117 if k in populate_dict:
117 if k in populate_dict:
118 setattr(self, k, populate_dict[k])
118 setattr(self, k, populate_dict[k])
119
119
120 @classmethod
120 @classmethod
121 def query(cls):
121 def query(cls):
122 return Session.query(cls)
122 return Session.query(cls)
123
123
124 @classmethod
124 @classmethod
125 def get(cls, id_):
125 def get(cls, id_):
126 return Session.query(cls).get(id_)
126 return Session.query(cls).get(id_)
127
127
128
128
129 class RhodeCodeSettings(Base, BaseModel):
129 class RhodeCodeSettings(Base, BaseModel):
130 __tablename__ = 'rhodecode_settings'
130 __tablename__ = 'rhodecode_settings'
131 __table_args__ = (UniqueConstraint('app_settings_name'), {'extend_existing':True})
131 __table_args__ = (UniqueConstraint('app_settings_name'), {'extend_existing':True})
132 app_settings_id = Column("app_settings_id", Integer(), nullable=False, unique=True, default=None, primary_key=True)
132 app_settings_id = Column("app_settings_id", Integer(), nullable=False, unique=True, default=None, primary_key=True)
133 app_settings_name = Column("app_settings_name", String(length=255, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
133 app_settings_name = Column("app_settings_name", String(length=255, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
134 app_settings_value = Column("app_settings_value", String(length=255, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
134 app_settings_value = Column("app_settings_value", String(length=255, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
135
135
136 def __init__(self, k='', v=''):
136 def __init__(self, k='', v=''):
137 self.app_settings_name = k
137 self.app_settings_name = k
138 self.app_settings_value = v
138 self.app_settings_value = v
139
139
140 def __repr__(self):
140 def __repr__(self):
141 return "<%s('%s:%s')>" % (self.__class__.__name__,
141 return "<%s('%s:%s')>" % (self.__class__.__name__,
142 self.app_settings_name, self.app_settings_value)
142 self.app_settings_name, self.app_settings_value)
143
143
144
144
145 @classmethod
145 @classmethod
146 def get_by_name(cls, ldap_key):
146 def get_by_name(cls, ldap_key):
147 return Session.query(cls)\
147 return Session.query(cls)\
148 .filter(cls.app_settings_name == ldap_key).scalar()
148 .filter(cls.app_settings_name == ldap_key).scalar()
149
149
150 @classmethod
150 @classmethod
151 def get_app_settings(cls, cache=False):
151 def get_app_settings(cls, cache=False):
152
152
153 ret = Session.query(cls)
153 ret = Session.query(cls)
154
154
155 if cache:
155 if cache:
156 ret = ret.options(FromCache("sql_cache_short", "get_hg_settings"))
156 ret = ret.options(FromCache("sql_cache_short", "get_hg_settings"))
157
157
158 if not ret:
158 if not ret:
159 raise Exception('Could not get application settings !')
159 raise Exception('Could not get application settings !')
160 settings = {}
160 settings = {}
161 for each in ret:
161 for each in ret:
162 settings['rhodecode_' + each.app_settings_name] = \
162 settings['rhodecode_' + each.app_settings_name] = \
163 each.app_settings_value
163 each.app_settings_value
164
164
165 return settings
165 return settings
166
166
167 @classmethod
167 @classmethod
168 def get_ldap_settings(cls, cache=False):
168 def get_ldap_settings(cls, cache=False):
169 ret = Session.query(cls)\
169 ret = Session.query(cls)\
170 .filter(cls.app_settings_name.startswith('ldap_'))\
170 .filter(cls.app_settings_name.startswith('ldap_'))\
171 .all()
171 .all()
172 fd = {}
172 fd = {}
173 for row in ret:
173 for row in ret:
174 fd.update({row.app_settings_name:row.app_settings_value})
174 fd.update({row.app_settings_name:row.app_settings_value})
175
175
176 fd.update({'ldap_active':str2bool(fd.get('ldap_active'))})
176 fd.update({'ldap_active':str2bool(fd.get('ldap_active'))})
177
177
178 return fd
178 return fd
179
179
180
180
181 class RhodeCodeUi(Base, BaseModel):
181 class RhodeCodeUi(Base, BaseModel):
182 __tablename__ = 'rhodecode_ui'
182 __tablename__ = 'rhodecode_ui'
183 __table_args__ = {'extend_existing':True}
183 __table_args__ = {'extend_existing':True}
184 ui_id = Column("ui_id", Integer(), nullable=False, unique=True, default=None, primary_key=True)
184 ui_id = Column("ui_id", Integer(), nullable=False, unique=True, default=None, primary_key=True)
185 ui_section = Column("ui_section", String(length=255, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
185 ui_section = Column("ui_section", String(length=255, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
186 ui_key = Column("ui_key", String(length=255, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
186 ui_key = Column("ui_key", String(length=255, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
187 ui_value = Column("ui_value", String(length=255, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
187 ui_value = Column("ui_value", String(length=255, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
188 ui_active = Column("ui_active", Boolean(), nullable=True, unique=None, default=True)
188 ui_active = Column("ui_active", Boolean(), nullable=True, unique=None, default=True)
189
189
190
190
191 @classmethod
191 @classmethod
192 def get_by_key(cls, key):
192 def get_by_key(cls, key):
193 return Session.query(cls).filter(cls.ui_key == key)
193 return Session.query(cls).filter(cls.ui_key == key)
194
194
195
195
196 class User(Base, BaseModel):
196 class User(Base, BaseModel):
197 __tablename__ = 'users'
197 __tablename__ = 'users'
198 __table_args__ = (UniqueConstraint('username'), UniqueConstraint('email'), {'extend_existing':True})
198 __table_args__ = (UniqueConstraint('username'), UniqueConstraint('email'), {'extend_existing':True})
199 user_id = Column("user_id", Integer(), nullable=False, unique=True, default=None, primary_key=True)
199 user_id = Column("user_id", Integer(), nullable=False, unique=True, default=None, primary_key=True)
200 username = Column("username", String(length=255, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
200 username = Column("username", String(length=255, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
201 password = Column("password", String(length=255, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
201 password = Column("password", String(length=255, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
202 active = Column("active", Boolean(), nullable=True, unique=None, default=None)
202 active = Column("active", Boolean(), nullable=True, unique=None, default=None)
203 admin = Column("admin", Boolean(), nullable=True, unique=None, default=False)
203 admin = Column("admin", Boolean(), nullable=True, unique=None, default=False)
204 name = Column("name", String(length=255, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
204 name = Column("name", String(length=255, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
205 lastname = Column("lastname", String(length=255, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
205 lastname = Column("lastname", String(length=255, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
206 email = Column("email", String(length=255, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
206 email = Column("email", String(length=255, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
207 last_login = Column("last_login", DateTime(timezone=False), nullable=True, unique=None, default=None)
207 last_login = Column("last_login", DateTime(timezone=False), nullable=True, unique=None, default=None)
208 ldap_dn = Column("ldap_dn", String(length=255, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
208 ldap_dn = Column("ldap_dn", String(length=255, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
209 api_key = Column("api_key", String(length=255, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
209 api_key = Column("api_key", String(length=255, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
210
210
211 user_log = relationship('UserLog', cascade='all')
211 user_log = relationship('UserLog', cascade='all')
212 user_perms = relationship('UserToPerm', primaryjoin="User.user_id==UserToPerm.user_id", cascade='all')
212 user_perms = relationship('UserToPerm', primaryjoin="User.user_id==UserToPerm.user_id", cascade='all')
213
213
214 repositories = relationship('Repository')
214 repositories = relationship('Repository')
215 user_followers = relationship('UserFollowing', primaryjoin='UserFollowing.follows_user_id==User.user_id', cascade='all')
215 user_followers = relationship('UserFollowing', primaryjoin='UserFollowing.follows_user_id==User.user_id', cascade='all')
216 repo_to_perm = relationship('RepoToPerm', primaryjoin='RepoToPerm.user_id==User.user_id', cascade='all')
216 repo_to_perm = relationship('RepoToPerm', primaryjoin='RepoToPerm.user_id==User.user_id', cascade='all')
217
217
218 group_member = relationship('UsersGroupMember', cascade='all')
218 group_member = relationship('UsersGroupMember', cascade='all')
219
219
220 @property
220 @property
221 def full_contact(self):
221 def full_contact(self):
222 return '%s %s <%s>' % (self.name, self.lastname, self.email)
222 return '%s %s <%s>' % (self.name, self.lastname, self.email)
223
223
224 @property
224 @property
225 def short_contact(self):
225 def short_contact(self):
226 return '%s %s' % (self.name, self.lastname)
226 return '%s %s' % (self.name, self.lastname)
227
227
228 @property
228 @property
229 def is_admin(self):
229 def is_admin(self):
230 return self.admin
230 return self.admin
231
231
232 def __repr__(self):
232 def __repr__(self):
233 try:
233 try:
234 return "<%s('id:%s:%s')>" % (self.__class__.__name__,
234 return "<%s('id:%s:%s')>" % (self.__class__.__name__,
235 self.user_id, self.username)
235 self.user_id, self.username)
236 except:
236 except:
237 return self.__class__.__name__
237 return self.__class__.__name__
238
238
239 @classmethod
239 @classmethod
240 def by_username(cls, username, case_insensitive=False):
240 def by_username(cls, username, case_insensitive=False):
241 if case_insensitive:
241 if case_insensitive:
242 return Session.query(cls).filter(cls.username.like(username)).one()
242 return Session.query(cls).filter(cls.username.like(username)).one()
243 else:
243 else:
244 return Session.query(cls).filter(cls.username == username).one()
244 return Session.query(cls).filter(cls.username == username).one()
245
245
246 @classmethod
246 @classmethod
247 def get_by_api_key(cls, api_key):
247 def get_by_api_key(cls, api_key):
248 return Session.query(cls).filter(cls.api_key == api_key).one()
248 return Session.query(cls).filter(cls.api_key == api_key).one()
249
249
250
250
251 def update_lastlogin(self):
251 def update_lastlogin(self):
252 """Update user lastlogin"""
252 """Update user lastlogin"""
253
253
254 self.last_login = datetime.datetime.now()
254 self.last_login = datetime.datetime.now()
255 Session.add(self)
255 Session.add(self)
256 Session.commit()
256 Session.commit()
257 log.debug('updated user %s lastlogin', self.username)
257 log.debug('updated user %s lastlogin', self.username)
258
258
259
259
260 class UserLog(Base, BaseModel):
260 class UserLog(Base, BaseModel):
261 __tablename__ = 'user_logs'
261 __tablename__ = 'user_logs'
262 __table_args__ = {'extend_existing':True}
262 __table_args__ = {'extend_existing':True}
263 user_log_id = Column("user_log_id", Integer(), nullable=False, unique=True, default=None, primary_key=True)
263 user_log_id = Column("user_log_id", Integer(), nullable=False, unique=True, default=None, primary_key=True)
264 user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None)
264 user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None)
265 repository_id = Column("repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=False, unique=None, default=None)
265 repository_id = Column("repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=False, unique=None, default=None)
266 repository_name = Column("repository_name", String(length=255, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
266 repository_name = Column("repository_name", String(length=255, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
267 user_ip = Column("user_ip", String(length=255, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
267 user_ip = Column("user_ip", String(length=255, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
268 action = Column("action", UnicodeText(length=1200000, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
268 action = Column("action", UnicodeText(length=1200000, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
269 action_date = Column("action_date", DateTime(timezone=False), nullable=True, unique=None, default=None)
269 action_date = Column("action_date", DateTime(timezone=False), nullable=True, unique=None, default=None)
270
270
271 @property
271 @property
272 def action_as_day(self):
272 def action_as_day(self):
273 return date(*self.action_date.timetuple()[:3])
273 return date(*self.action_date.timetuple()[:3])
274
274
275 user = relationship('User')
275 user = relationship('User')
276 repository = relationship('Repository')
276 repository = relationship('Repository')
277
277
278
278
279 class UsersGroup(Base, BaseModel):
279 class UsersGroup(Base, BaseModel):
280 __tablename__ = 'users_groups'
280 __tablename__ = 'users_groups'
281 __table_args__ = {'extend_existing':True}
281 __table_args__ = {'extend_existing':True}
282
282
283 users_group_id = Column("users_group_id", Integer(), nullable=False, unique=True, default=None, primary_key=True)
283 users_group_id = Column("users_group_id", Integer(), nullable=False, unique=True, default=None, primary_key=True)
284 users_group_name = Column("users_group_name", String(length=255, convert_unicode=False, assert_unicode=None), nullable=False, unique=True, default=None)
284 users_group_name = Column("users_group_name", String(length=255, convert_unicode=False, assert_unicode=None), nullable=False, unique=True, default=None)
285 users_group_active = Column("users_group_active", Boolean(), nullable=True, unique=None, default=None)
285 users_group_active = Column("users_group_active", Boolean(), nullable=True, unique=None, default=None)
286
286
287 members = relationship('UsersGroupMember', cascade="all, delete, delete-orphan", lazy="joined")
287 members = relationship('UsersGroupMember', cascade="all, delete, delete-orphan", lazy="joined")
288
288
289
289
290 @classmethod
290 @classmethod
291 def get_by_group_name(cls, group_name, cache=False, case_insensitive=False):
291 def get_by_group_name(cls, group_name, cache=False, case_insensitive=False):
292 if case_insensitive:
292 if case_insensitive:
293 gr = Session.query(cls)\
293 gr = Session.query(cls)\
294 .filter(cls.users_group_name.ilike(group_name))
294 .filter(cls.users_group_name.ilike(group_name))
295 else:
295 else:
296 gr = Session.query(UsersGroup)\
296 gr = Session.query(UsersGroup)\
297 .filter(UsersGroup.users_group_name == group_name)
297 .filter(UsersGroup.users_group_name == group_name)
298 if cache:
298 if cache:
299 gr = gr.options(FromCache("sql_cache_short",
299 gr = gr.options(FromCache("sql_cache_short",
300 "get_user_%s" % group_name))
300 "get_user_%s" % group_name))
301 return gr.scalar()
301 return gr.scalar()
302
302
303 class UsersGroupMember(Base, BaseModel):
303 class UsersGroupMember(Base, BaseModel):
304 __tablename__ = 'users_groups_members'
304 __tablename__ = 'users_groups_members'
305 __table_args__ = {'extend_existing':True}
305 __table_args__ = {'extend_existing':True}
306
306
307 users_group_member_id = Column("users_group_member_id", Integer(), nullable=False, unique=True, default=None, primary_key=True)
307 users_group_member_id = Column("users_group_member_id", Integer(), nullable=False, unique=True, default=None, primary_key=True)
308 users_group_id = Column("users_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None)
308 users_group_id = Column("users_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None)
309 user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None)
309 user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None)
310
310
311 user = relationship('User', lazy='joined')
311 user = relationship('User', lazy='joined')
312 users_group = relationship('UsersGroup')
312 users_group = relationship('UsersGroup')
313
313
314 def __init__(self, gr_id='', u_id=''):
314 def __init__(self, gr_id='', u_id=''):
315 self.users_group_id = gr_id
315 self.users_group_id = gr_id
316 self.user_id = u_id
316 self.user_id = u_id
317
317
318 class Repository(Base, BaseModel):
318 class Repository(Base, BaseModel):
319 __tablename__ = 'repositories'
319 __tablename__ = 'repositories'
320 __table_args__ = (UniqueConstraint('repo_name'), {'extend_existing':True},)
320 __table_args__ = (UniqueConstraint('repo_name'), {'extend_existing':True},)
321
321
322 repo_id = Column("repo_id", Integer(), nullable=False, unique=True, default=None, primary_key=True)
322 repo_id = Column("repo_id", Integer(), nullable=False, unique=True, default=None, primary_key=True)
323 repo_name = Column("repo_name", String(length=255, convert_unicode=False, assert_unicode=None), nullable=False, unique=True, default=None)
323 repo_name = Column("repo_name", String(length=255, convert_unicode=False, assert_unicode=None), nullable=False, unique=True, default=None)
324 clone_uri = Column("clone_uri", String(length=255, convert_unicode=False, assert_unicode=None), nullable=True, unique=False, default=None)
324 clone_uri = Column("clone_uri", String(length=255, convert_unicode=False, assert_unicode=None), nullable=True, unique=False, default=None)
325 repo_type = Column("repo_type", String(length=255, convert_unicode=False, assert_unicode=None), nullable=False, unique=False, default='hg')
325 repo_type = Column("repo_type", String(length=255, convert_unicode=False, assert_unicode=None), nullable=False, unique=False, default='hg')
326 user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=False, default=None)
326 user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=False, default=None)
327 private = Column("private", Boolean(), nullable=True, unique=None, default=None)
327 private = Column("private", Boolean(), nullable=True, unique=None, default=None)
328 enable_statistics = Column("statistics", Boolean(), nullable=True, unique=None, default=True)
328 enable_statistics = Column("statistics", Boolean(), nullable=True, unique=None, default=True)
329 enable_downloads = Column("downloads", Boolean(), nullable=True, unique=None, default=True)
329 enable_downloads = Column("downloads", Boolean(), nullable=True, unique=None, default=True)
330 description = Column("description", String(length=10000, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
330 description = Column("description", String(length=10000, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
331 created_on = Column('created_on', DateTime(timezone=False), nullable=True, unique=None, default=datetime.datetime.now)
331 created_on = Column('created_on', DateTime(timezone=False), nullable=True, unique=None, default=datetime.datetime.now)
332
332
333 fork_id = Column("fork_id", Integer(), ForeignKey('repositories.repo_id'), nullable=True, unique=False, default=None)
333 fork_id = Column("fork_id", Integer(), ForeignKey('repositories.repo_id'), nullable=True, unique=False, default=None)
334 group_id = Column("group_id", Integer(), ForeignKey('groups.group_id'), nullable=True, unique=False, default=None)
334 group_id = Column("group_id", Integer(), ForeignKey('groups.group_id'), nullable=True, unique=False, default=None)
335
335
336
336
337 user = relationship('User')
337 user = relationship('User')
338 fork = relationship('Repository', remote_side=repo_id)
338 fork = relationship('Repository', remote_side=repo_id)
339 group = relationship('Group')
339 group = relationship('Group')
340 repo_to_perm = relationship('RepoToPerm', cascade='all', order_by='RepoToPerm.repo_to_perm_id')
340 repo_to_perm = relationship('RepoToPerm', cascade='all', order_by='RepoToPerm.repo_to_perm_id')
341 users_group_to_perm = relationship('UsersGroupRepoToPerm', cascade='all')
341 users_group_to_perm = relationship('UsersGroupRepoToPerm', cascade='all')
342 stats = relationship('Statistics', cascade='all', uselist=False)
342 stats = relationship('Statistics', cascade='all', uselist=False)
343
343
344 followers = relationship('UserFollowing', primaryjoin='UserFollowing.follows_repo_id==Repository.repo_id', cascade='all')
344 followers = relationship('UserFollowing', primaryjoin='UserFollowing.follows_repo_id==Repository.repo_id', cascade='all')
345
345
346 logs = relationship('UserLog', cascade='all')
346 logs = relationship('UserLog', cascade='all')
347
347
348 def __repr__(self):
348 def __repr__(self):
349 return "<%s('%s:%s')>" % (self.__class__.__name__,
349 return "<%s('%s:%s')>" % (self.__class__.__name__,
350 self.repo_id, self.repo_name)
350 self.repo_id, self.repo_name)
351
351
352 @classmethod
352 @classmethod
353 def by_repo_name(cls, repo_name):
353 def by_repo_name(cls, repo_name):
354 q = Session.query(cls).filter(cls.repo_name == repo_name)
354 q = Session.query(cls).filter(cls.repo_name == repo_name)
355
355
356 q = q.options(joinedload(Repository.fork))\
356 q = q.options(joinedload(Repository.fork))\
357 .options(joinedload(Repository.user))\
357 .options(joinedload(Repository.user))\
358 .options(joinedload(Repository.group))\
358 .options(joinedload(Repository.group))\
359
359
360 return q.one()
360 return q.one()
361
361
362 @classmethod
362 @classmethod
363 def get_repo_forks(cls, repo_id):
363 def get_repo_forks(cls, repo_id):
364 return Session.query(cls).filter(Repository.fork_id == repo_id)
364 return Session.query(cls).filter(Repository.fork_id == repo_id)
365
365
366 @property
366 @property
367 def just_name(self):
367 def just_name(self):
368 return self.repo_name.split(os.sep)[-1]
368 return self.repo_name.split(os.sep)[-1]
369
369
370 @property
370 @property
371 def groups_with_parents(self):
371 def groups_with_parents(self):
372 groups = []
372 groups = []
373 if self.group is None:
373 if self.group is None:
374 return groups
374 return groups
375
375
376 cur_gr = self.group
376 cur_gr = self.group
377 groups.insert(0, cur_gr)
377 groups.insert(0, cur_gr)
378 while 1:
378 while 1:
379 gr = getattr(cur_gr, 'parent_group', None)
379 gr = getattr(cur_gr, 'parent_group', None)
380 cur_gr = cur_gr.parent_group
380 cur_gr = cur_gr.parent_group
381 if gr is None:
381 if gr is None:
382 break
382 break
383 groups.insert(0, gr)
383 groups.insert(0, gr)
384
384
385 return groups
385 return groups
386
386
387 @property
387 @property
388 def groups_and_repo(self):
388 def groups_and_repo(self):
389 return self.groups_with_parents, self.just_name
389 return self.groups_with_parents, self.just_name
390
390
391 @LazyProperty
391 @LazyProperty
392 def repo_path(self):
392 def repo_path(self):
393 """
393 """
394 Returns base full path for that repository means where it actually
394 Returns base full path for that repository means where it actually
395 exists on a filesystem
395 exists on a filesystem
396 """
396 """
397 q = Session.query(RhodeCodeUi).filter(RhodeCodeUi.ui_key == '/')
397 q = Session.query(RhodeCodeUi).filter(RhodeCodeUi.ui_key == '/')
398 q.options(FromCache("sql_cache_short", "repository_repo_path"))
398 q.options(FromCache("sql_cache_short", "repository_repo_path"))
399 return q.one().ui_value
399 return q.one().ui_value
400
400
401 @property
401 @property
402 def repo_full_path(self):
402 def repo_full_path(self):
403 p = [self.repo_path]
403 p = [self.repo_path]
404 # we need to split the name by / since this is how we store the
404 # we need to split the name by / since this is how we store the
405 # names in the database, but that eventually needs to be converted
405 # names in the database, but that eventually needs to be converted
406 # into a valid system path
406 # into a valid system path
407 p += self.repo_name.split('/')
407 p += self.repo_name.split('/')
408 return os.path.join(*p)
408 return os.path.join(*p)
409
409
410 @property
410 @property
411 def _ui(self):
411 def _ui(self):
412 """
412 """
413 Creates an db based ui object for this repository
413 Creates an db based ui object for this repository
414 """
414 """
415 from mercurial import ui
415 from mercurial import ui
416 from mercurial import config
416 from mercurial import config
417 baseui = ui.ui()
417 baseui = ui.ui()
418
418
419 #clean the baseui object
419 #clean the baseui object
420 baseui._ocfg = config.config()
420 baseui._ocfg = config.config()
421 baseui._ucfg = config.config()
421 baseui._ucfg = config.config()
422 baseui._tcfg = config.config()
422 baseui._tcfg = config.config()
423
423
424
424
425 ret = Session.query(RhodeCodeUi)\
425 ret = Session.query(RhodeCodeUi)\
426 .options(FromCache("sql_cache_short",
426 .options(FromCache("sql_cache_short",
427 "repository_repo_ui")).all()
427 "repository_repo_ui")).all()
428
428
429 hg_ui = ret
429 hg_ui = ret
430 for ui_ in hg_ui:
430 for ui_ in hg_ui:
431 if ui_.ui_active:
431 if ui_.ui_active:
432 log.debug('settings ui from db[%s]%s:%s', ui_.ui_section,
432 log.debug('settings ui from db[%s]%s:%s', ui_.ui_section,
433 ui_.ui_key, ui_.ui_value)
433 ui_.ui_key, ui_.ui_value)
434 baseui.setconfig(ui_.ui_section, ui_.ui_key, ui_.ui_value)
434 baseui.setconfig(ui_.ui_section, ui_.ui_key, ui_.ui_value)
435
435
436 return baseui
436 return baseui
437
437
438 #==========================================================================
438 #==========================================================================
439 # SCM CACHE INSTANCE
439 # SCM CACHE INSTANCE
440 #==========================================================================
440 #==========================================================================
441
441
442 @property
442 @property
443 def invalidate(self):
443 def invalidate(self):
444 """
444 """
445 Returns Invalidation object if this repo should be invalidated
445 Returns Invalidation object if this repo should be invalidated
446 None otherwise. `cache_active = False` means that this cache
446 None otherwise. `cache_active = False` means that this cache
447 state is not valid and needs to be invalidated
447 state is not valid and needs to be invalidated
448 """
448 """
449 return Session.query(CacheInvalidation)\
449 return Session.query(CacheInvalidation)\
450 .filter(CacheInvalidation.cache_key == self.repo_name)\
450 .filter(CacheInvalidation.cache_key == self.repo_name)\
451 .filter(CacheInvalidation.cache_active == False)\
451 .filter(CacheInvalidation.cache_active == False)\
452 .scalar()
452 .scalar()
453
453
454 @property
454 @property
455 def set_invalidate(self):
455 def set_invalidate(self):
456 """
456 """
457 set a cache for invalidation for this instance
457 set a cache for invalidation for this instance
458 """
458 """
459 inv = Session.query(CacheInvalidation)\
459 inv = Session.query(CacheInvalidation)\
460 .filter(CacheInvalidation.cache_key == self.repo_name)\
460 .filter(CacheInvalidation.cache_key == self.repo_name)\
461 .scalar()
461 .scalar()
462
462
463 if inv is None:
463 if inv is None:
464 inv = CacheInvalidation(self.repo_name)
464 inv = CacheInvalidation(self.repo_name)
465 inv.cache_active = True
465 inv.cache_active = True
466 Session.add(inv)
466 Session.add(inv)
467 Session.commit()
467 Session.commit()
468
468
469 @property
469 @property
470 def scm_instance(self):
470 def scm_instance(self):
471 return self.__get_instance()
471 return self.__get_instance()
472
472
473 @property
473 @property
474 def scm_instance_cached(self):
474 def scm_instance_cached(self):
475 @cache_region('long_term')
475 @cache_region('long_term')
476 def _c(repo_name):
476 def _c(repo_name):
477 return self.__get_instance()
477 return self.__get_instance()
478
478
479 inv = self.invalidate
479 inv = self.invalidate
480 if inv:
480 if inv is not None:
481 region_invalidate(_c, None, self.repo_name)
481 region_invalidate(_c, None, self.repo_name)
482 #update our cache
482 #update our cache
483 inv.cache_key.cache_active = True
483 inv.cache_active = True
484 Session.add(inv)
484 Session.add(inv)
485 Session.commit()
485 Session.commit()
486
486
487 # TODO: remove this trick when beaker 1.6 is released
487 # TODO: remove this trick when beaker 1.6 is released
488 # and have fixed this issue
488 # and have fixed this issue
489 rn = safe_str(self.repo_name)
489 rn = safe_str(self.repo_name)
490
490
491 return _c(rn)
491 return _c(rn)
492
492
493 def __get_instance(self):
493 def __get_instance(self):
494
494
495 repo_full_path = self.repo_full_path
495 repo_full_path = self.repo_full_path
496
496
497 try:
497 try:
498 alias = get_scm(repo_full_path)[0]
498 alias = get_scm(repo_full_path)[0]
499 log.debug('Creating instance of %s repository', alias)
499 log.debug('Creating instance of %s repository', alias)
500 backend = get_backend(alias)
500 backend = get_backend(alias)
501 except VCSError:
501 except VCSError:
502 log.error(traceback.format_exc())
502 log.error(traceback.format_exc())
503 log.error('Perhaps this repository is in db and not in '
503 log.error('Perhaps this repository is in db and not in '
504 'filesystem run rescan repositories with '
504 'filesystem run rescan repositories with '
505 '"destroy old data " option from admin panel')
505 '"destroy old data " option from admin panel')
506 return
506 return
507
507
508 if alias == 'hg':
508 if alias == 'hg':
509
509
510 repo = backend(safe_str(repo_full_path), create=False,
510 repo = backend(safe_str(repo_full_path), create=False,
511 baseui=self._ui)
511 baseui=self._ui)
512 #skip hidden web repository
512 #skip hidden web repository
513 if repo._get_hidden():
513 if repo._get_hidden():
514 return
514 return
515 else:
515 else:
516 repo = backend(repo_full_path, create=False)
516 repo = backend(repo_full_path, create=False)
517
517
518 return repo
518 return repo
519
519
520
520
521 class Group(Base, BaseModel):
521 class Group(Base, BaseModel):
522 __tablename__ = 'groups'
522 __tablename__ = 'groups'
523 __table_args__ = (UniqueConstraint('group_name', 'group_parent_id'),
523 __table_args__ = (UniqueConstraint('group_name', 'group_parent_id'),
524 CheckConstraint('group_id != group_parent_id'), {'extend_existing':True},)
524 CheckConstraint('group_id != group_parent_id'), {'extend_existing':True},)
525 __mapper_args__ = {'order_by':'group_name'}
525 __mapper_args__ = {'order_by':'group_name'}
526
526
527 group_id = Column("group_id", Integer(), nullable=False, unique=True, default=None, primary_key=True)
527 group_id = Column("group_id", Integer(), nullable=False, unique=True, default=None, primary_key=True)
528 group_name = Column("group_name", String(length=255, convert_unicode=False, assert_unicode=None), nullable=False, unique=True, default=None)
528 group_name = Column("group_name", String(length=255, convert_unicode=False, assert_unicode=None), nullable=False, unique=True, default=None)
529 group_parent_id = Column("group_parent_id", Integer(), ForeignKey('groups.group_id'), nullable=True, unique=None, default=None)
529 group_parent_id = Column("group_parent_id", Integer(), ForeignKey('groups.group_id'), nullable=True, unique=None, default=None)
530 group_description = Column("group_description", String(length=10000, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
530 group_description = Column("group_description", String(length=10000, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
531
531
532 parent_group = relationship('Group', remote_side=group_id)
532 parent_group = relationship('Group', remote_side=group_id)
533
533
534
534
535 def __init__(self, group_name='', parent_group=None):
535 def __init__(self, group_name='', parent_group=None):
536 self.group_name = group_name
536 self.group_name = group_name
537 self.parent_group = parent_group
537 self.parent_group = parent_group
538
538
539 def __repr__(self):
539 def __repr__(self):
540 return "<%s('%s:%s')>" % (self.__class__.__name__, self.group_id,
540 return "<%s('%s:%s')>" % (self.__class__.__name__, self.group_id,
541 self.group_name)
541 self.group_name)
542
542
543 @classmethod
543 @classmethod
544 def url_sep(cls):
544 def url_sep(cls):
545 return '/'
545 return '/'
546
546
547 @property
547 @property
548 def parents(self):
548 def parents(self):
549 parents_recursion_limit = 5
549 parents_recursion_limit = 5
550 groups = []
550 groups = []
551 if self.parent_group is None:
551 if self.parent_group is None:
552 return groups
552 return groups
553 cur_gr = self.parent_group
553 cur_gr = self.parent_group
554 groups.insert(0, cur_gr)
554 groups.insert(0, cur_gr)
555 cnt = 0
555 cnt = 0
556 while 1:
556 while 1:
557 cnt += 1
557 cnt += 1
558 gr = getattr(cur_gr, 'parent_group', None)
558 gr = getattr(cur_gr, 'parent_group', None)
559 cur_gr = cur_gr.parent_group
559 cur_gr = cur_gr.parent_group
560 if gr is None:
560 if gr is None:
561 break
561 break
562 if cnt == parents_recursion_limit:
562 if cnt == parents_recursion_limit:
563 # this will prevent accidental infinit loops
563 # this will prevent accidental infinit loops
564 log.error('group nested more than %s' %
564 log.error('group nested more than %s' %
565 parents_recursion_limit)
565 parents_recursion_limit)
566 break
566 break
567
567
568 groups.insert(0, gr)
568 groups.insert(0, gr)
569 return groups
569 return groups
570
570
571 @property
571 @property
572 def children(self):
572 def children(self):
573 return Session.query(Group).filter(Group.parent_group == self)
573 return Session.query(Group).filter(Group.parent_group == self)
574
574
575 @property
575 @property
576 def full_path(self):
576 def full_path(self):
577 return Group.url_sep().join([g.group_name for g in self.parents] +
577 return Group.url_sep().join([g.group_name for g in self.parents] +
578 [self.group_name])
578 [self.group_name])
579
579
580 @property
580 @property
581 def repositories(self):
581 def repositories(self):
582 return Session.query(Repository).filter(Repository.group == self)
582 return Session.query(Repository).filter(Repository.group == self)
583
583
584 @property
584 @property
585 def repositories_recursive_count(self):
585 def repositories_recursive_count(self):
586 cnt = self.repositories.count()
586 cnt = self.repositories.count()
587
587
588 def children_count(group):
588 def children_count(group):
589 cnt = 0
589 cnt = 0
590 for child in group.children:
590 for child in group.children:
591 cnt += child.repositories.count()
591 cnt += child.repositories.count()
592 cnt += children_count(child)
592 cnt += children_count(child)
593 return cnt
593 return cnt
594
594
595 return cnt + children_count(self)
595 return cnt + children_count(self)
596
596
597 class Permission(Base, BaseModel):
597 class Permission(Base, BaseModel):
598 __tablename__ = 'permissions'
598 __tablename__ = 'permissions'
599 __table_args__ = {'extend_existing':True}
599 __table_args__ = {'extend_existing':True}
600 permission_id = Column("permission_id", Integer(), nullable=False, unique=True, default=None, primary_key=True)
600 permission_id = Column("permission_id", Integer(), nullable=False, unique=True, default=None, primary_key=True)
601 permission_name = Column("permission_name", String(length=255, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
601 permission_name = Column("permission_name", String(length=255, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
602 permission_longname = Column("permission_longname", String(length=255, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
602 permission_longname = Column("permission_longname", String(length=255, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
603
603
604 def __repr__(self):
604 def __repr__(self):
605 return "<%s('%s:%s')>" % (self.__class__.__name__,
605 return "<%s('%s:%s')>" % (self.__class__.__name__,
606 self.permission_id, self.permission_name)
606 self.permission_id, self.permission_name)
607
607
608 @classmethod
608 @classmethod
609 def get_by_key(cls, key):
609 def get_by_key(cls, key):
610 return Session.query(cls).filter(cls.permission_name == key).scalar()
610 return Session.query(cls).filter(cls.permission_name == key).scalar()
611
611
612 class RepoToPerm(Base, BaseModel):
612 class RepoToPerm(Base, BaseModel):
613 __tablename__ = 'repo_to_perm'
613 __tablename__ = 'repo_to_perm'
614 __table_args__ = (UniqueConstraint('user_id', 'repository_id'), {'extend_existing':True})
614 __table_args__ = (UniqueConstraint('user_id', 'repository_id'), {'extend_existing':True})
615 repo_to_perm_id = Column("repo_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True)
615 repo_to_perm_id = Column("repo_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True)
616 user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None)
616 user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None)
617 permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None)
617 permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None)
618 repository_id = Column("repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=False, unique=None, default=None)
618 repository_id = Column("repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=False, unique=None, default=None)
619
619
620 user = relationship('User')
620 user = relationship('User')
621 permission = relationship('Permission')
621 permission = relationship('Permission')
622 repository = relationship('Repository')
622 repository = relationship('Repository')
623
623
624 class UserToPerm(Base, BaseModel):
624 class UserToPerm(Base, BaseModel):
625 __tablename__ = 'user_to_perm'
625 __tablename__ = 'user_to_perm'
626 __table_args__ = (UniqueConstraint('user_id', 'permission_id'), {'extend_existing':True})
626 __table_args__ = (UniqueConstraint('user_id', 'permission_id'), {'extend_existing':True})
627 user_to_perm_id = Column("user_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True)
627 user_to_perm_id = Column("user_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True)
628 user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None)
628 user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None)
629 permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None)
629 permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None)
630
630
631 user = relationship('User')
631 user = relationship('User')
632 permission = relationship('Permission')
632 permission = relationship('Permission')
633
633
634 @classmethod
634 @classmethod
635 def has_perm(cls, user_id, perm):
635 def has_perm(cls, user_id, perm):
636 if not isinstance(perm, Permission):
636 if not isinstance(perm, Permission):
637 raise Exception('perm needs to be an instance of Permission class')
637 raise Exception('perm needs to be an instance of Permission class')
638
638
639 return Session.query(cls).filter(cls.user_id == user_id)\
639 return Session.query(cls).filter(cls.user_id == user_id)\
640 .filter(cls.permission == perm).scalar() is not None
640 .filter(cls.permission == perm).scalar() is not None
641
641
642 @classmethod
642 @classmethod
643 def grant_perm(cls, user_id, perm):
643 def grant_perm(cls, user_id, perm):
644 if not isinstance(perm, Permission):
644 if not isinstance(perm, Permission):
645 raise Exception('perm needs to be an instance of Permission class')
645 raise Exception('perm needs to be an instance of Permission class')
646
646
647 new = cls()
647 new = cls()
648 new.user_id = user_id
648 new.user_id = user_id
649 new.permission = perm
649 new.permission = perm
650 try:
650 try:
651 Session.add(new)
651 Session.add(new)
652 Session.commit()
652 Session.commit()
653 except:
653 except:
654 Session.rollback()
654 Session.rollback()
655
655
656
656
657 @classmethod
657 @classmethod
658 def revoke_perm(cls, user_id, perm):
658 def revoke_perm(cls, user_id, perm):
659 if not isinstance(perm, Permission):
659 if not isinstance(perm, Permission):
660 raise Exception('perm needs to be an instance of Permission class')
660 raise Exception('perm needs to be an instance of Permission class')
661
661
662 try:
662 try:
663 Session.query(cls).filter(cls.user_id == user_id)\
663 Session.query(cls).filter(cls.user_id == user_id)\
664 .filter(cls.permission == perm).delete()
664 .filter(cls.permission == perm).delete()
665 Session.commit()
665 Session.commit()
666 except:
666 except:
667 Session.rollback()
667 Session.rollback()
668
668
669 class UsersGroupRepoToPerm(Base, BaseModel):
669 class UsersGroupRepoToPerm(Base, BaseModel):
670 __tablename__ = 'users_group_repo_to_perm'
670 __tablename__ = 'users_group_repo_to_perm'
671 __table_args__ = (UniqueConstraint('repository_id', 'users_group_id', 'permission_id'), {'extend_existing':True})
671 __table_args__ = (UniqueConstraint('repository_id', 'users_group_id', 'permission_id'), {'extend_existing':True})
672 users_group_to_perm_id = Column("users_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True)
672 users_group_to_perm_id = Column("users_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True)
673 users_group_id = Column("users_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None)
673 users_group_id = Column("users_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None)
674 permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None)
674 permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None)
675 repository_id = Column("repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=False, unique=None, default=None)
675 repository_id = Column("repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=False, unique=None, default=None)
676
676
677 users_group = relationship('UsersGroup')
677 users_group = relationship('UsersGroup')
678 permission = relationship('Permission')
678 permission = relationship('Permission')
679 repository = relationship('Repository')
679 repository = relationship('Repository')
680
680
681
681
682 class UsersGroupToPerm(Base, BaseModel):
682 class UsersGroupToPerm(Base, BaseModel):
683 __tablename__ = 'users_group_to_perm'
683 __tablename__ = 'users_group_to_perm'
684 users_group_to_perm_id = Column("users_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True)
684 users_group_to_perm_id = Column("users_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True)
685 users_group_id = Column("users_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None)
685 users_group_id = Column("users_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None)
686 permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None)
686 permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None)
687
687
688 users_group = relationship('UsersGroup')
688 users_group = relationship('UsersGroup')
689 permission = relationship('Permission')
689 permission = relationship('Permission')
690
690
691
691
692 @classmethod
692 @classmethod
693 def has_perm(cls, users_group_id, perm):
693 def has_perm(cls, users_group_id, perm):
694 if not isinstance(perm, Permission):
694 if not isinstance(perm, Permission):
695 raise Exception('perm needs to be an instance of Permission class')
695 raise Exception('perm needs to be an instance of Permission class')
696
696
697 return Session.query(cls).filter(cls.users_group_id ==
697 return Session.query(cls).filter(cls.users_group_id ==
698 users_group_id)\
698 users_group_id)\
699 .filter(cls.permission == perm)\
699 .filter(cls.permission == perm)\
700 .scalar() is not None
700 .scalar() is not None
701
701
702 @classmethod
702 @classmethod
703 def grant_perm(cls, users_group_id, perm):
703 def grant_perm(cls, users_group_id, perm):
704 if not isinstance(perm, Permission):
704 if not isinstance(perm, Permission):
705 raise Exception('perm needs to be an instance of Permission class')
705 raise Exception('perm needs to be an instance of Permission class')
706
706
707 new = cls()
707 new = cls()
708 new.users_group_id = users_group_id
708 new.users_group_id = users_group_id
709 new.permission = perm
709 new.permission = perm
710 try:
710 try:
711 Session.add(new)
711 Session.add(new)
712 Session.commit()
712 Session.commit()
713 except:
713 except:
714 Session.rollback()
714 Session.rollback()
715
715
716
716
717 @classmethod
717 @classmethod
718 def revoke_perm(cls, users_group_id, perm):
718 def revoke_perm(cls, users_group_id, perm):
719 if not isinstance(perm, Permission):
719 if not isinstance(perm, Permission):
720 raise Exception('perm needs to be an instance of Permission class')
720 raise Exception('perm needs to be an instance of Permission class')
721
721
722 try:
722 try:
723 Session.query(cls).filter(cls.users_group_id == users_group_id)\
723 Session.query(cls).filter(cls.users_group_id == users_group_id)\
724 .filter(cls.permission == perm).delete()
724 .filter(cls.permission == perm).delete()
725 Session.commit()
725 Session.commit()
726 except:
726 except:
727 Session.rollback()
727 Session.rollback()
728
728
729
729
730 class GroupToPerm(Base, BaseModel):
730 class GroupToPerm(Base, BaseModel):
731 __tablename__ = 'group_to_perm'
731 __tablename__ = 'group_to_perm'
732 __table_args__ = (UniqueConstraint('group_id', 'permission_id'), {'extend_existing':True})
732 __table_args__ = (UniqueConstraint('group_id', 'permission_id'), {'extend_existing':True})
733
733
734 group_to_perm_id = Column("group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True)
734 group_to_perm_id = Column("group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True)
735 user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None)
735 user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None)
736 permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None)
736 permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None)
737 group_id = Column("group_id", Integer(), ForeignKey('groups.group_id'), nullable=False, unique=None, default=None)
737 group_id = Column("group_id", Integer(), ForeignKey('groups.group_id'), nullable=False, unique=None, default=None)
738
738
739 user = relationship('User')
739 user = relationship('User')
740 permission = relationship('Permission')
740 permission = relationship('Permission')
741 group = relationship('Group')
741 group = relationship('Group')
742
742
743 class Statistics(Base, BaseModel):
743 class Statistics(Base, BaseModel):
744 __tablename__ = 'statistics'
744 __tablename__ = 'statistics'
745 __table_args__ = (UniqueConstraint('repository_id'), {'extend_existing':True})
745 __table_args__ = (UniqueConstraint('repository_id'), {'extend_existing':True})
746 stat_id = Column("stat_id", Integer(), nullable=False, unique=True, default=None, primary_key=True)
746 stat_id = Column("stat_id", Integer(), nullable=False, unique=True, default=None, primary_key=True)
747 repository_id = Column("repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=False, unique=True, default=None)
747 repository_id = Column("repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=False, unique=True, default=None)
748 stat_on_revision = Column("stat_on_revision", Integer(), nullable=False)
748 stat_on_revision = Column("stat_on_revision", Integer(), nullable=False)
749 commit_activity = Column("commit_activity", LargeBinary(1000000), nullable=False)#JSON data
749 commit_activity = Column("commit_activity", LargeBinary(1000000), nullable=False)#JSON data
750 commit_activity_combined = Column("commit_activity_combined", LargeBinary(), nullable=False)#JSON data
750 commit_activity_combined = Column("commit_activity_combined", LargeBinary(), nullable=False)#JSON data
751 languages = Column("languages", LargeBinary(1000000), nullable=False)#JSON data
751 languages = Column("languages", LargeBinary(1000000), nullable=False)#JSON data
752
752
753 repository = relationship('Repository', single_parent=True)
753 repository = relationship('Repository', single_parent=True)
754
754
755 class UserFollowing(Base, BaseModel):
755 class UserFollowing(Base, BaseModel):
756 __tablename__ = 'user_followings'
756 __tablename__ = 'user_followings'
757 __table_args__ = (UniqueConstraint('user_id', 'follows_repository_id'),
757 __table_args__ = (UniqueConstraint('user_id', 'follows_repository_id'),
758 UniqueConstraint('user_id', 'follows_user_id')
758 UniqueConstraint('user_id', 'follows_user_id')
759 , {'extend_existing':True})
759 , {'extend_existing':True})
760
760
761 user_following_id = Column("user_following_id", Integer(), nullable=False, unique=True, default=None, primary_key=True)
761 user_following_id = Column("user_following_id", Integer(), nullable=False, unique=True, default=None, primary_key=True)
762 user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None)
762 user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None)
763 follows_repo_id = Column("follows_repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=True, unique=None, default=None)
763 follows_repo_id = Column("follows_repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=True, unique=None, default=None)
764 follows_user_id = Column("follows_user_id", Integer(), ForeignKey('users.user_id'), nullable=True, unique=None, default=None)
764 follows_user_id = Column("follows_user_id", Integer(), ForeignKey('users.user_id'), nullable=True, unique=None, default=None)
765 follows_from = Column('follows_from', DateTime(timezone=False), nullable=True, unique=None, default=datetime.datetime.now)
765 follows_from = Column('follows_from', DateTime(timezone=False), nullable=True, unique=None, default=datetime.datetime.now)
766
766
767 user = relationship('User', primaryjoin='User.user_id==UserFollowing.user_id')
767 user = relationship('User', primaryjoin='User.user_id==UserFollowing.user_id')
768
768
769 follows_user = relationship('User', primaryjoin='User.user_id==UserFollowing.follows_user_id')
769 follows_user = relationship('User', primaryjoin='User.user_id==UserFollowing.follows_user_id')
770 follows_repository = relationship('Repository', order_by='Repository.repo_name')
770 follows_repository = relationship('Repository', order_by='Repository.repo_name')
771
771
772
772
773 @classmethod
773 @classmethod
774 def get_repo_followers(cls, repo_id):
774 def get_repo_followers(cls, repo_id):
775 return Session.query(cls).filter(cls.follows_repo_id == repo_id)
775 return Session.query(cls).filter(cls.follows_repo_id == repo_id)
776
776
777 class CacheInvalidation(Base, BaseModel):
777 class CacheInvalidation(Base, BaseModel):
778 __tablename__ = 'cache_invalidation'
778 __tablename__ = 'cache_invalidation'
779 __table_args__ = (UniqueConstraint('cache_key'), {'extend_existing':True})
779 __table_args__ = (UniqueConstraint('cache_key'), {'extend_existing':True})
780 cache_id = Column("cache_id", Integer(), nullable=False, unique=True, default=None, primary_key=True)
780 cache_id = Column("cache_id", Integer(), nullable=False, unique=True, default=None, primary_key=True)
781 cache_key = Column("cache_key", String(length=255, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
781 cache_key = Column("cache_key", String(length=255, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
782 cache_args = Column("cache_args", String(length=255, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
782 cache_args = Column("cache_args", String(length=255, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
783 cache_active = Column("cache_active", Boolean(), nullable=True, unique=None, default=False)
783 cache_active = Column("cache_active", Boolean(), nullable=True, unique=None, default=False)
784
784
785
785
786 def __init__(self, cache_key, cache_args=''):
786 def __init__(self, cache_key, cache_args=''):
787 self.cache_key = cache_key
787 self.cache_key = cache_key
788 self.cache_args = cache_args
788 self.cache_args = cache_args
789 self.cache_active = False
789 self.cache_active = False
790
790
791 def __repr__(self):
791 def __repr__(self):
792 return "<%s('%s:%s')>" % (self.__class__.__name__,
792 return "<%s('%s:%s')>" % (self.__class__.__name__,
793 self.cache_id, self.cache_key)
793 self.cache_id, self.cache_key)
794
794
795 class DbMigrateVersion(Base, BaseModel):
795 class DbMigrateVersion(Base, BaseModel):
796 __tablename__ = 'db_migrate_version'
796 __tablename__ = 'db_migrate_version'
797 __table_args__ = {'extend_existing':True}
797 __table_args__ = {'extend_existing':True}
798 repository_id = Column('repository_id', String(250), primary_key=True)
798 repository_id = Column('repository_id', String(250), primary_key=True)
799 repository_path = Column('repository_path', Text)
799 repository_path = Column('repository_path', Text)
800 version = Column('version', Integer)
800 version = Column('version', Integer)
General Comments 0
You need to be logged in to leave comments. Login now