comparison rhodecode/model/db.py @ 2357:ea079c9b62b5 codereview

merge with beta
author Marcin Kuzminski <marcin@python-works.com>
date Mon, 28 May 2012 23:35:30 +0200
parents 8fe7c1024719 2da7b5984ae5
children d4e555e32cfb
comparison
equal deleted inserted replaced
2355:29a8096820dc 2357:ea079c9b62b5
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 import hashlib
30 from collections import defaultdict 31 from collections import defaultdict
31 32
32 from sqlalchemy import * 33 from sqlalchemy import *
33 from sqlalchemy.ext.hybrid import hybrid_property 34 from sqlalchemy.ext.hybrid import hybrid_property
34 from sqlalchemy.orm import relationship, joinedload, class_mapper, validates 35 from sqlalchemy.orm import relationship, joinedload, class_mapper, validates
36 from sqlalchemy.exc import DatabaseError
35 from beaker.cache import cache_region, region_invalidate 37 from beaker.cache import cache_region, region_invalidate
36 38
37 from pylons.i18n.translation import lazy_ugettext as _ 39 from pylons.i18n.translation import lazy_ugettext as _
38 40
39 from rhodecode.lib.vcs import get_backend 41 from rhodecode.lib.vcs import get_backend
45 safe_unicode 47 safe_unicode
46 from rhodecode.lib.compat import json 48 from rhodecode.lib.compat import json
47 from rhodecode.lib.caching_query import FromCache 49 from rhodecode.lib.caching_query import FromCache
48 50
49 from rhodecode.model.meta import Base, Session 51 from rhodecode.model.meta import Base, Session
50 import hashlib 52
51 from sqlalchemy.exc import DatabaseError
52 53
53 URL_SEP = '/' 54 URL_SEP = '/'
54 log = logging.getLogger(__name__) 55 log = logging.getLogger(__name__)
55 56
56 #============================================================================== 57 #==============================================================================
152 def __repr__(self): 153 def __repr__(self):
153 if hasattr(self, '__unicode__'): 154 if hasattr(self, '__unicode__'):
154 # python repr needs to return str 155 # python repr needs to return str
155 return safe_str(self.__unicode__()) 156 return safe_str(self.__unicode__())
156 return '<DB:%s>' % (self.__class__.__name__) 157 return '<DB:%s>' % (self.__class__.__name__)
158
157 159
158 class RhodeCodeSetting(Base, BaseModel): 160 class RhodeCodeSetting(Base, BaseModel):
159 __tablename__ = 'rhodecode_settings' 161 __tablename__ = 'rhodecode_settings'
160 __table_args__ = ( 162 __table_args__ = (
161 UniqueConstraint('app_settings_name'), 163 UniqueConstraint('app_settings_name'),
223 def get_ldap_settings(cls, cache=False): 225 def get_ldap_settings(cls, cache=False):
224 ret = cls.query()\ 226 ret = cls.query()\
225 .filter(cls.app_settings_name.startswith('ldap_')).all() 227 .filter(cls.app_settings_name.startswith('ldap_')).all()
226 fd = {} 228 fd = {}
227 for row in ret: 229 for row in ret:
228 fd.update({row.app_settings_name:row.app_settings_value}) 230 fd.update({row.app_settings_name: row.app_settings_value})
229 231
230 return fd 232 return fd
231 233
232 234
233 class RhodeCodeUi(Base, BaseModel): 235 class RhodeCodeUi(Base, BaseModel):
759 761
760 @LazyProperty 762 @LazyProperty
761 def scm_instance(self): 763 def scm_instance(self):
762 return self.__get_instance() 764 return self.__get_instance()
763 765
764 @property 766 def scm_instance_cached(self, cache_map=None):
765 def scm_instance_cached(self):
766 @cache_region('long_term') 767 @cache_region('long_term')
767 def _c(repo_name): 768 def _c(repo_name):
768 return self.__get_instance() 769 return self.__get_instance()
769 rn = self.repo_name 770 rn = self.repo_name
770 log.debug('Getting cached instance of repo') 771 log.debug('Getting cached instance of repo')
771 inv = self.invalidate 772
772 if inv is not None: 773 if cache_map:
774 # get using prefilled cache_map
775 invalidate_repo = cache_map[self.repo_name]
776 if invalidate_repo:
777 invalidate_repo = (None if invalidate_repo.cache_active
778 else invalidate_repo)
779 else:
780 # get from invalidate
781 invalidate_repo = self.invalidate
782
783 if invalidate_repo is not None:
773 region_invalidate(_c, None, rn) 784 region_invalidate(_c, None, rn)
774 # update our cache 785 # update our cache
775 CacheInvalidation.set_valid(inv.cache_key) 786 CacheInvalidation.set_valid(invalidate_repo.cache_key)
776 return _c(rn) 787 return _c(rn)
777 788
778 def __get_instance(self): 789 def __get_instance(self):
779 repo_full_path = self.repo_full_path 790 repo_full_path = self.repo_full_path
780 try: 791 try:
1138 1149
1139 class CacheInvalidation(Base, BaseModel): 1150 class CacheInvalidation(Base, BaseModel):
1140 __tablename__ = 'cache_invalidation' 1151 __tablename__ = 'cache_invalidation'
1141 __table_args__ = ( 1152 __table_args__ = (
1142 UniqueConstraint('cache_key'), 1153 UniqueConstraint('cache_key'),
1154 Index('key_idx', 'cache_key'),
1143 {'extend_existing': True, 'mysql_engine': 'InnoDB', 1155 {'extend_existing': True, 'mysql_engine': 'InnoDB',
1144 'mysql_charset': 'utf8'}, 1156 'mysql_charset': 'utf8'},
1145 ) 1157 )
1146 cache_id = Column("cache_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) 1158 cache_id = Column("cache_id", Integer(), nullable=False, unique=True, default=None, primary_key=True)
1147 cache_key = Column("cache_key", String(length=255, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None) 1159 cache_key = Column("cache_key", String(length=255, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
1154 self.cache_active = False 1166 self.cache_active = False
1155 1167
1156 def __unicode__(self): 1168 def __unicode__(self):
1157 return u"<%s('%s:%s')>" % (self.__class__.__name__, 1169 return u"<%s('%s:%s')>" % (self.__class__.__name__,
1158 self.cache_id, self.cache_key) 1170 self.cache_id, self.cache_key)
1171
1159 @classmethod 1172 @classmethod
1160 def clear_cache(cls): 1173 def clear_cache(cls):
1161 cls.query().delete() 1174 cls.query().delete()
1162 1175
1163 @classmethod 1176 @classmethod
1240 inv_obj = cls.get_by_key(key) 1253 inv_obj = cls.get_by_key(key)
1241 inv_obj.cache_active = True 1254 inv_obj.cache_active = True
1242 Session.add(inv_obj) 1255 Session.add(inv_obj)
1243 Session.commit() 1256 Session.commit()
1244 1257
1258 @classmethod
1259 def get_cache_map(cls):
1260
1261 class cachemapdict(dict):
1262
1263 def __init__(self, *args, **kwargs):
1264 fixkey = kwargs.get('fixkey')
1265 if fixkey:
1266 del kwargs['fixkey']
1267 self.fixkey = fixkey
1268 super(cachemapdict, self).__init__(*args, **kwargs)
1269
1270 def __getattr__(self, name):
1271 key = name
1272 if self.fixkey:
1273 key, _prefix, _org_key = cls._get_key(key)
1274 if key in self.__dict__:
1275 return self.__dict__[key]
1276 else:
1277 return self[key]
1278
1279 def __getitem__(self, key):
1280 if self.fixkey:
1281 key, _prefix, _org_key = cls._get_key(key)
1282 try:
1283 return super(cachemapdict, self).__getitem__(key)
1284 except KeyError:
1285 return
1286
1287 cache_map = cachemapdict(fixkey=True)
1288 for obj in cls.query().all():
1289 cache_map[obj.cache_key] = cachemapdict(obj.get_dict())
1290 return cache_map
1291
1245 1292
1246 class ChangesetComment(Base, BaseModel): 1293 class ChangesetComment(Base, BaseModel):
1247 __tablename__ = 'changeset_comments' 1294 __tablename__ = 'changeset_comments'
1248 __table_args__ = ( 1295 __table_args__ = (
1249 {'extend_existing': True, 'mysql_engine': 'InnoDB', 1296 {'extend_existing': True, 'mysql_engine': 'InnoDB',