Changeset 692
- Timestamp:
- 09/25/05 17:03:30 (3 years ago)
- Files:
-
- django/trunk/django/bin/django-admin.py (modified) (3 diffs)
- django/trunk/django/core/cache.py (modified) (4 diffs)
- django/trunk/django/core/management.py (modified) (1 diff)
- django/trunk/docs/cache.txt (modified) (1 diff)
- django/trunk/docs/django-admin.txt (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
django/trunk/django/bin/django-admin.py
r606 r692 7 7 'adminindex': management.get_admin_index, 8 8 'createsuperuser': management.createsuperuser, 9 'createcachetable' : management.createcachetable, 9 10 # 'dbcheck': management.database_check, 10 11 'init': management.init, … … 24 25 } 25 26 26 NO_SQL_TRANSACTION = ('adminindex', ' dbcheck', 'install', 'sqlindexes')27 NO_SQL_TRANSACTION = ('adminindex', 'createcachetable', 'dbcheck', 'install', 'sqlindexes') 27 28 28 29 def get_usage(): … … 80 81 sys.stderr.write("Error: %r isn't supported for the currently selected database backend.\n" % action) 81 82 sys.exit(1) 83 elif action == 'createcachetable': 84 try: 85 ACTION_MAPPING[action](args[1]) 86 except IndexError: 87 parser.print_usage_and_exit() 82 88 elif action in ('startapp', 'startproject'): 83 89 try: django/trunk/django/core/cache.py
r686 r692 16 16 on localhost port 11211. 17 17 18 sql://tablename/ A SQL backend. If you use this backend, 19 you must have django.contrib.cache in 20 INSTALLED_APPS, and you must have installed 21 the tables for django.contrib.cache. 18 db://tablename/ A database backend in a table named 19 "tablename". This table should be created 20 with "django-admin createcachetable". 22 21 23 22 file:///var/tmp/django_cache/ A file-based cache stored in the directory … … 56 55 57 56 memcached://127.0.0.1:11211/?timeout=60 58 sql://tablename/?timeout=120&max_entries=500&cull_percentage=457 db://tablename/?timeout=120&max_entries=500&cull_percentage=4 59 58 60 59 Invalid arguments are silently ignored, as are invalid values of known … … 351 350 def _key_to_file(self, key): 352 351 return os.path.join(self._dir, urllib.quote_plus(key)) 352 353 ############# 354 # SQL cache # 355 ############# 356 357 import base64 358 from django.core.db import db 359 from datetime import datetime 360 361 class _DBCache(_Cache): 362 """SQL cache backend""" 353 363 364 def __init__(self, table, params): 365 _Cache.__init__(self, params) 366 self._table = table 367 max_entries = params.get('max_entries', 300) 368 try: 369 self._max_entries = int(max_entries) 370 except (ValueError, TypeError): 371 self._max_entries = 300 372 cull_frequency = params.get('cull_frequency', 3) 373 try: 374 self._cull_frequency = int(cull_frequency) 375 except (ValueError, TypeError): 376 self._cull_frequency = 3 377 378 def get(self, key, default=None): 379 cursor = db.cursor() 380 cursor.execute("SELECT key, value, expires FROM %s WHERE key = %%s" % self._table, [key]) 381 row = cursor.fetchone() 382 if row is None: 383 return default 384 now = datetime.now() 385 if row[2] < now: 386 cursor.execute("DELETE FROM %s WHERE key = %%s" % self._table, [key]) 387 db.commit() 388 return default 389 return pickle.loads(base64.decodestring(row[1])) 390 391 def set(self, key, value, timeout=None): 392 if timeout is None: 393 timeout = self.default_timeout 394 cursor = db.cursor() 395 cursor.execute("SELECT COUNT(*) FROM %s" % self._table) 396 num = cursor.fetchone()[0] 397 now = datetime.now().replace(microsecond=0) 398 exp = datetime.fromtimestamp(time.time() + timeout).replace(microsecond=0) 399 if num > self._max_entries: 400 self._cull(cursor, now) 401 encoded = base64.encodestring(pickle.dumps(value, 2)).strip() 402 cursor.execute("SELECT key FROM %s WHERE key = %%s" % self._table, [key]) 403 if cursor.fetchone(): 404 cursor.execute("UPDATE %s SET value = %%s, expires = %%s WHERE key = %%s" % self._table, [encoded, str(exp), key]) 405 else: 406 cursor.execute("INSERT INTO %s (key, value, expires) VALUES (%%s, %%s, %%s)" % self._table, [key, encoded, str(exp)]) 407 db.commit() 408 409 def delete(self, key): 410 cursor = db.cursor() 411 cursor.execute("DELETE FROM %s WHERE key = %%s" % self._table, [key]) 412 db.commit() 413 414 def has_key(self, key): 415 cursor = db.cursor() 416 cursor.execute("SELECT key FROM %s WHERE key = %%s" % self._table, [key]) 417 return cursor.fetchone() is not None 418 419 def _cull(self, cursor, now): 420 if self._cull_frequency == 0: 421 cursor.execute("DELETE FROM %s" % self._table) 422 else: 423 cursor.execute("DELETE FROM %s WHERE expires < %%s" % self._table, [str(now)]) 424 cursor.execute("SELECT COUNT(*) FROM %s" % self._table) 425 num = cursor.fetchone()[0] 426 if num > self._max_entries: 427 cursor.execute("SELECT key FROM %s ORDER BY key LIMIT 1 OFFSET %%s" % self._table, [num / self._cull_frequency]) 428 cursor.execute("DELETE FROM %s WHERE key < %%s" % self._table, [cursor.fetchone()[0]]) 429 354 430 ########################################## 355 431 # Read settings and load a cache backend # … … 363 439 'locmem' : _LocMemCache, 364 440 'file' : _FileCache, 441 'db' : _DBCache, 365 442 } 366 443 django/trunk/django/core/management.py
r685 r692 622 622 autoreload.main(inner_run) 623 623 runserver.args = '[optional port number, or ipaddr:port]' 624 625 def createcachetable(tablename): 626 "Creates the table needed to use the SQL cache backend" 627 from django.core import db, meta 628 fields = ( 629 meta.CharField(name='key', maxlength=255, unique=True, primary_key=True), 630 meta.TextField(name='value'), 631 meta.DateTimeField(name='expires', db_index=True), 632 ) 633 table_output = [] 634 index_output = [] 635 for f in fields: 636 field_output = [f.column, db.DATA_TYPES[f.__class__.__name__] % f.__dict__] 637 field_output.append("%sNULL" % (not f.null and "NOT " or "")) 638 if f.unique: 639 field_output.append("UNIQUE") 640 if f.primary_key: 641 field_output.append("PRIMARY KEY") 642 if f.db_index: 643 unique = f.unique and "UNIQUE " or "" 644 index_output.append("CREATE %sINDEX %s_%s ON %s (%s);" % (unique, tablename, f.column, tablename, f.column)) 645 table_output.append(" ".join(field_output)) 646 full_statement = ["CREATE TABLE %s (" % tablename] 647 for i, line in enumerate(table_output): 648 full_statement.append(' %s%s' % (line, i < len(table_output)-1 and ',' or '')) 649 full_statement.append(');') 650 curs = db.db.cursor() 651 curs.execute("\n".join(full_statement)) 652 for statement in index_output: 653 curs.execute(statement) 654 db.db.commit() 655 createcachetable.args = "[tablename]" django/trunk/docs/cache.txt
r633 r692 30 30 on localhost port 11211. 31 31 32 db://tablename/ A database backend in a table named 33 "tablename". This table should be created 34 with "django-admin createcachetable". 35 36 file:///var/tmp/django_cache/ A file-based cache stored in the directory 37 /var/tmp/django_cache/. 38 32 39 simple:/// A simple single-process memory cache; you 33 40 probably don't want to use this except for 34 41 testing. Note that this cache backend is 35 42 NOT threadsafe! 43 44 locmem:/// A more sophisticaed local memory cache; 45 this is multi-process- and thread-safe. 36 46 ============================== =========================================== 37 47 django/trunk/docs/django-admin.txt
r612 r692 41 41 .. _Tutorial 2: http://www.djangoproject.com/documentation/tutorial2/ 42 42 43 createcachetable [tablename] 44 ---------------------------- 45 46 Creates a cache table named ``tablename`` for use with the database cache 47 backend. See the `cache documentation`_ for more information. 48 49 .. _cache documentation: http://www.djangoproject.com/documentation/cache/ 50 43 51 createsuperuser 44 52 ---------------
