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