mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
IDEA-72909 Fix annotate pattern for Mercurial
1. Spacing alignment between date and line number was changed in hg 1.9.
Make the pattern more flexible.
2. Fix leading spaces being added to the author name.
3. Test parsing of the annotate output (HgAnnotateCommand.parse) for 3 versions of Mercurial.
Move parse functionality of HgAnnotateCommand to a separate method.
4. Implement equals, hashCode for HgAnnotationLine.
[Reviewed by irengrig]
This commit is contained in:
@@ -22,6 +22,7 @@ import org.zmlx.hg4idea.execution.HgCommandResult;
|
||||
import org.zmlx.hg4idea.provider.annotate.HgAnnotationLine;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
@@ -29,7 +30,7 @@ import java.util.regex.Pattern;
|
||||
public class HgAnnotateCommand {
|
||||
|
||||
private static final Pattern LINE_PATTERN = Pattern.compile(
|
||||
"(.+)\\s+([0-9]+)\\s+([0-9a-f]+)\\s+([0-9]{4}-[0-9]{2}-[0-9]{2}):([0-9]+):\\s(.*)"
|
||||
"\\s*(.+)\\s+([0-9]+)\\s+([0-9a-fA-F]+)\\s+([0-9]{4}-[0-9]{2}-[0-9]{2}):\\s*([0-9]+):\\s(.*)"
|
||||
);
|
||||
|
||||
private static final int USER_GROUP = 1;
|
||||
@@ -39,10 +40,10 @@ public class HgAnnotateCommand {
|
||||
private static final int LINE_NUMBER_GROUP = 5;
|
||||
private static final int CONTENT_GROUP = 6;
|
||||
|
||||
private final Project project;
|
||||
private final Project myProject;
|
||||
|
||||
public HgAnnotateCommand(Project project) {
|
||||
this.project = project;
|
||||
myProject = project;
|
||||
}
|
||||
|
||||
public List<HgAnnotationLine> execute(@NotNull HgFile hgFile, VcsFileRevision revision) {
|
||||
@@ -54,14 +55,19 @@ public class HgAnnotateCommand {
|
||||
arguments.add(revisionNumber.getChangeset());
|
||||
}
|
||||
arguments.add(hgFile.getRelativePath());
|
||||
final HgCommandResult result = new HgCommandExecutor(project).executeInCurrentThread(hgFile.getRepo(), "annotate", arguments);
|
||||
final HgCommandResult result = new HgCommandExecutor(myProject).executeInCurrentThread(hgFile.getRepo(), "annotate", arguments);
|
||||
|
||||
final List<HgAnnotationLine> annotations = new ArrayList<HgAnnotationLine>();
|
||||
if (result == null) {
|
||||
return annotations;
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
for (String line : result.getOutputLines()) {
|
||||
List<String> outputLines = result.getOutputLines();
|
||||
return parse(outputLines);
|
||||
}
|
||||
|
||||
private static List<HgAnnotationLine> parse(List<String> outputLines) {
|
||||
List<HgAnnotationLine> annotations = new ArrayList<HgAnnotationLine>(outputLines.size());
|
||||
for (String line : outputLines) {
|
||||
Matcher matcher = LINE_PATTERN.matcher(line);
|
||||
if (matcher.matches()) {
|
||||
String user = matcher.group(USER_GROUP);
|
||||
|
||||
@@ -38,4 +38,20 @@ public class HgAnnotationLine {
|
||||
return fields.get(field);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj) {
|
||||
return true;
|
||||
}
|
||||
if (!(obj instanceof HgAnnotationLine)) {
|
||||
return false;
|
||||
}
|
||||
HgAnnotationLine other = (HgAnnotationLine) obj;
|
||||
return fields.equals(other.fields);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return fields.hashCode();
|
||||
}
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,3 @@
|
||||
The source - a file with huge history from the hg repository of the Django project: https://bitbucket.org/django/django/
|
||||
File: /Users/loki/temp/django/django/core/cache/backends/db.py
|
||||
Last revision at the time of parsing: bf038debb499 (13.07.11 13:35)
|
||||
@@ -0,0 +1,149 @@
|
||||
adrian 2287 3f0790d500a9 2006-02-24:1: "Database cache backend."
|
||||
jezdez 16338 bf038debb499 2011-07-13:2: import base64
|
||||
jezdez 16338 bf038debb499 2011-07-13:3: import time
|
||||
jezdez 16338 bf038debb499 2011-07-13:4: from datetime import datetime
|
||||
adrian 2287 3f0790d500a9 2006-02-24:2:
|
||||
adrian 2287 3f0790d500a9 2006-02-24:7: try:
|
||||
adrian 2287 3f0790d500a9 2006-02-24:8: import cPickle as pickle
|
||||
adrian 2287 3f0790d500a9 2006-02-24:9: except ImportError:
|
||||
adrian 2287 3f0790d500a9 2006-02-24:10: import pickle
|
||||
adrian 2287 3f0790d500a9 2006-02-24:11:
|
||||
jezdez 16338 bf038debb499 2011-07-13:11: from django.core.cache.backends.base import BaseCache
|
||||
jezdez 16338 bf038debb499 2011-07-13:12: from django.db import connections, router, transaction, DatabaseError
|
||||
jezdez 16338 bf038debb499 2011-07-13:13:
|
||||
jezdez 16338 bf038debb499 2011-07-13:14:
|
||||
russellm 13275 4dd52d4f3f50 2010-08-05:12: class Options(object):
|
||||
russellm 13275 4dd52d4f3f50 2010-08-05:13: """A class that will quack like a Django model _meta class.
|
||||
russellm 13275 4dd52d4f3f50 2010-08-05:14:
|
||||
russellm 13275 4dd52d4f3f50 2010-08-05:15: This allows cache operations to be controlled by the router
|
||||
russellm 13275 4dd52d4f3f50 2010-08-05:16: """
|
||||
russellm 13275 4dd52d4f3f50 2010-08-05:17: def __init__(self, table):
|
||||
russellm 13275 4dd52d4f3f50 2010-08-05:18: self.db_table = table
|
||||
russellm 13275 4dd52d4f3f50 2010-08-05:19: self.app_label = 'django_cache'
|
||||
russellm 13275 4dd52d4f3f50 2010-08-05:20: self.module_name = 'cacheentry'
|
||||
russellm 13275 4dd52d4f3f50 2010-08-05:21: self.verbose_name = 'cache entry'
|
||||
russellm 13275 4dd52d4f3f50 2010-08-05:22: self.verbose_name_plural = 'cache entries'
|
||||
russellm 13275 4dd52d4f3f50 2010-08-05:23: self.object_name = 'CacheEntry'
|
||||
russellm 13275 4dd52d4f3f50 2010-08-05:24: self.abstract = False
|
||||
russellm 13275 4dd52d4f3f50 2010-08-05:25: self.managed = True
|
||||
russellm 13275 4dd52d4f3f50 2010-08-05:26: self.proxy = False
|
||||
russellm 13275 4dd52d4f3f50 2010-08-05:27:
|
||||
russellm 14807 905c4a7e1f19 2010-12-21:28: class BaseDatabaseCache(BaseCache):
|
||||
russellm 14807 905c4a7e1f19 2010-12-21:29: def __init__(self, table, params):
|
||||
russellm 14807 905c4a7e1f19 2010-12-21:30: BaseCache.__init__(self, params)
|
||||
russellm 13275 4dd52d4f3f50 2010-08-05:31: self._table = table
|
||||
russellm 13275 4dd52d4f3f50 2010-08-05:32:
|
||||
russellm 13275 4dd52d4f3f50 2010-08-05:33: class CacheEntry(object):
|
||||
russellm 13275 4dd52d4f3f50 2010-08-05:34: _meta = Options(table)
|
||||
russellm 13275 4dd52d4f3f50 2010-08-05:35: self.cache_model_class = CacheEntry
|
||||
russellm 13275 4dd52d4f3f50 2010-08-05:36:
|
||||
russellm 14807 905c4a7e1f19 2010-12-21:37: class DatabaseCache(BaseDatabaseCache):
|
||||
russellm 14425 793e94ba2037 2010-11-19:38: def get(self, key, default=None, version=None):
|
||||
russellm 14425 793e94ba2037 2010-11-19:39: key = self.make_key(key, version=version)
|
||||
mtredinnick 13568 7e0b7bf098d2 2010-09-12:49: self.validate_key(key)
|
||||
russellm 13275 4dd52d4f3f50 2010-08-05:49: db = router.db_for_read(self.cache_model_class)
|
||||
russellm 13275 4dd52d4f3f50 2010-08-05:50: table = connections[db].ops.quote_name(self._table)
|
||||
russellm 13275 4dd52d4f3f50 2010-08-05:51: cursor = connections[db].cursor()
|
||||
russellm 13275 4dd52d4f3f50 2010-08-05:52:
|
||||
russellm 13275 4dd52d4f3f50 2010-08-05:53: cursor.execute("SELECT cache_key, value, expires FROM %s WHERE cache_key = %%s" % table, [key])
|
||||
adrian 2287 3f0790d500a9 2006-02-24:30: row = cursor.fetchone()
|
||||
adrian 2287 3f0790d500a9 2006-02-24:31: if row is None:
|
||||
adrian 2287 3f0790d500a9 2006-02-24:32: return default
|
||||
adrian 2287 3f0790d500a9 2006-02-24:33: now = datetime.now()
|
||||
adrian 2287 3f0790d500a9 2006-02-24:34: if row[2] < now:
|
||||
russellm 13275 4dd52d4f3f50 2010-08-05:59: db = router.db_for_write(self.cache_model_class)
|
||||
russellm 13275 4dd52d4f3f50 2010-08-05:60: cursor = connections[db].cursor()
|
||||
russellm 13275 4dd52d4f3f50 2010-08-05:61: cursor.execute("DELETE FROM %s WHERE cache_key = %%s" % table, [key])
|
||||
russellm 13275 4dd52d4f3f50 2010-08-05:62: transaction.commit_unless_managed(using=db)
|
||||
adrian 2287 3f0790d500a9 2006-02-24:37: return default
|
||||
russellm 13275 4dd52d4f3f50 2010-08-05:64: value = connections[db].ops.process_clob(row[1])
|
||||
ikelly 9862 8739c35149dd 2009-03-13:39: return pickle.loads(base64.decodestring(value))
|
||||
adrian 2287 3f0790d500a9 2006-02-24:39:
|
||||
russellm 14425 793e94ba2037 2010-11-19:59: def set(self, key, value, timeout=None, version=None):
|
||||
russellm 14425 793e94ba2037 2010-11-19:60: key = self.make_key(key, version=version)
|
||||
mtredinnick 13568 7e0b7bf098d2 2010-09-12:69: self.validate_key(key)
|
||||
mtredinnick 8110 c787c7f62142 2008-08-10:41: self._base_set('set', key, value, timeout)
|
||||
mtredinnick 6421 b4175804cc7b 2007-10-20:45:
|
||||
russellm 14425 793e94ba2037 2010-11-19:64: def add(self, key, value, timeout=None, version=None):
|
||||
russellm 14425 793e94ba2037 2010-11-19:65: key = self.make_key(key, version=version)
|
||||
mtredinnick 13568 7e0b7bf098d2 2010-09-12:73: self.validate_key(key)
|
||||
mtredinnick 6438 5096a56a9ac6 2007-10-21:44: return self._base_set('add', key, value, timeout)
|
||||
mtredinnick 6438 5096a56a9ac6 2007-10-21:45:
|
||||
mtredinnick 6421 b4175804cc7b 2007-10-20:46: def _base_set(self, mode, key, value, timeout=None):
|
||||
adrian 2287 3f0790d500a9 2006-02-24:41: if timeout is None:
|
||||
adrian 2287 3f0790d500a9 2006-02-24:42: timeout = self.default_timeout
|
||||
russellm 13275 4dd52d4f3f50 2010-08-05:76: db = router.db_for_write(self.cache_model_class)
|
||||
russellm 13275 4dd52d4f3f50 2010-08-05:77: table = connections[db].ops.quote_name(self._table)
|
||||
russellm 13275 4dd52d4f3f50 2010-08-05:78: cursor = connections[db].cursor()
|
||||
russellm 13275 4dd52d4f3f50 2010-08-05:79:
|
||||
russellm 13275 4dd52d4f3f50 2010-08-05:80: cursor.execute("SELECT COUNT(*) FROM %s" % table)
|
||||
adrian 2287 3f0790d500a9 2006-02-24:45: num = cursor.fetchone()[0]
|
||||
adrian 2287 3f0790d500a9 2006-02-24:46: now = datetime.now().replace(microsecond=0)
|
||||
adrian 2287 3f0790d500a9 2006-02-24:47: exp = datetime.fromtimestamp(time.time() + timeout).replace(microsecond=0)
|
||||
adrian 2287 3f0790d500a9 2006-02-24:48: if num > self._max_entries:
|
||||
russellm 13275 4dd52d4f3f50 2010-08-05:85: self._cull(db, cursor, now)
|
||||
adrian 2287 3f0790d500a9 2006-02-24:50: encoded = base64.encodestring(pickle.dumps(value, 2)).strip()
|
||||
russellm 13275 4dd52d4f3f50 2010-08-05:87: cursor.execute("SELECT cache_key, expires FROM %s WHERE cache_key = %%s" % table, [key])
|
||||
adrian 2287 3f0790d500a9 2006-02-24:52: try:
|
||||
mtredinnick 9753 0ab5ef23e1bc 2009-03-02:59: result = cursor.fetchone()
|
||||
mtredinnick 9753 0ab5ef23e1bc 2009-03-02:60: if result and (mode == 'set' or
|
||||
mtredinnick 9753 0ab5ef23e1bc 2009-03-02:61: (mode == 'add' and result[1] < now)):
|
||||
russellm 13275 4dd52d4f3f50 2010-08-05:92: cursor.execute("UPDATE %s SET value = %%s, expires = %%s WHERE cache_key = %%s" % table,
|
||||
russellm 13275 4dd52d4f3f50 2010-08-05:93: [encoded, connections[db].ops.value_to_db_datetime(exp), key])
|
||||
adrian 2287 3f0790d500a9 2006-02-24:55: else:
|
||||
russellm 13275 4dd52d4f3f50 2010-08-05:95: cursor.execute("INSERT INTO %s (cache_key, value, expires) VALUES (%%s, %%s, %%s)" % table,
|
||||
russellm 13275 4dd52d4f3f50 2010-08-05:96: [key, encoded, connections[db].ops.value_to_db_datetime(exp)])
|
||||
adrian 2287 3f0790d500a9 2006-02-24:57: except DatabaseError:
|
||||
adrian 2287 3f0790d500a9 2006-02-24:58: # To be threadsafe, updates/inserts are allowed to fail silently
|
||||
russellm 13275 4dd52d4f3f50 2010-08-05:99: transaction.rollback_unless_managed(using=db)
|
||||
mtredinnick 8110 c787c7f62142 2008-08-10:65: return False
|
||||
adrian 2287 3f0790d500a9 2006-02-24:60: else:
|
||||
russellm 13275 4dd52d4f3f50 2010-08-05:102: transaction.commit_unless_managed(using=db)
|
||||
mtredinnick 8110 c787c7f62142 2008-08-10:68: return True
|
||||
adrian 2287 3f0790d500a9 2006-02-24:62:
|
||||
russellm 14425 793e94ba2037 2010-11-19:101: def delete(self, key, version=None):
|
||||
russellm 14425 793e94ba2037 2010-11-19:102: key = self.make_key(key, version=version)
|
||||
mtredinnick 13568 7e0b7bf098d2 2010-09-12:109: self.validate_key(key)
|
||||
russellm 14425 793e94ba2037 2010-11-19:104:
|
||||
russellm 13275 4dd52d4f3f50 2010-08-05:106: db = router.db_for_write(self.cache_model_class)
|
||||
russellm 13275 4dd52d4f3f50 2010-08-05:107: table = connections[db].ops.quote_name(self._table)
|
||||
russellm 13275 4dd52d4f3f50 2010-08-05:108: cursor = connections[db].cursor()
|
||||
russellm 13275 4dd52d4f3f50 2010-08-05:109:
|
||||
russellm 13275 4dd52d4f3f50 2010-08-05:110: cursor.execute("DELETE FROM %s WHERE cache_key = %%s" % table, [key])
|
||||
russellm 13275 4dd52d4f3f50 2010-08-05:111: transaction.commit_unless_managed(using=db)
|
||||
adrian 2287 3f0790d500a9 2006-02-24:67:
|
||||
russellm 14425 793e94ba2037 2010-11-19:112: def has_key(self, key, version=None):
|
||||
russellm 14425 793e94ba2037 2010-11-19:113: key = self.make_key(key, version=version)
|
||||
mtredinnick 13568 7e0b7bf098d2 2010-09-12:118: self.validate_key(key)
|
||||
russellm 14425 793e94ba2037 2010-11-19:115:
|
||||
russellm 13275 4dd52d4f3f50 2010-08-05:114: db = router.db_for_read(self.cache_model_class)
|
||||
russellm 13275 4dd52d4f3f50 2010-08-05:115: table = connections[db].ops.quote_name(self._table)
|
||||
russellm 13275 4dd52d4f3f50 2010-08-05:116: cursor = connections[db].cursor()
|
||||
russellm 13275 4dd52d4f3f50 2010-08-05:117:
|
||||
mtredinnick 9753 0ab5ef23e1bc 2009-03-02:78: now = datetime.now().replace(microsecond=0)
|
||||
russellm 13275 4dd52d4f3f50 2010-08-05:119: cursor.execute("SELECT cache_key FROM %s WHERE cache_key = %%s and expires > %%s" % table,
|
||||
russellm 13275 4dd52d4f3f50 2010-08-05:120: [key, connections[db].ops.value_to_db_datetime(now)])
|
||||
adrian 2287 3f0790d500a9 2006-02-24:71: return cursor.fetchone() is not None
|
||||
adrian 2287 3f0790d500a9 2006-02-24:72:
|
||||
russellm 13275 4dd52d4f3f50 2010-08-05:123: def _cull(self, db, cursor, now):
|
||||
adrian 2287 3f0790d500a9 2006-02-24:74: if self._cull_frequency == 0:
|
||||
russellm 12116 c1ad14c551a9 2010-01-27:87: self.clear()
|
||||
adrian 2287 3f0790d500a9 2006-02-24:76: else:
|
||||
russellm 13480 7351411944a9 2010-08-31:127: table = connections[db].ops.quote_name(self._table)
|
||||
russellm 13275 4dd52d4f3f50 2010-08-05:127: cursor.execute("DELETE FROM %s WHERE expires < %%s" % table,
|
||||
russellm 13275 4dd52d4f3f50 2010-08-05:128: [connections[db].ops.value_to_db_datetime(now)])
|
||||
russellm 13275 4dd52d4f3f50 2010-08-05:129: cursor.execute("SELECT COUNT(*) FROM %s" % table)
|
||||
adrian 2287 3f0790d500a9 2006-02-24:79: num = cursor.fetchone()[0]
|
||||
adrian 2287 3f0790d500a9 2006-02-24:80: if num > self._max_entries:
|
||||
russellm 13275 4dd52d4f3f50 2010-08-05:132: cursor.execute("SELECT cache_key FROM %s ORDER BY cache_key LIMIT 1 OFFSET %%s" % table, [num / self._cull_frequency])
|
||||
russellm 13275 4dd52d4f3f50 2010-08-05:133: cursor.execute("DELETE FROM %s WHERE cache_key < %%s" % table, [cursor.fetchone()[0]])
|
||||
russellm 12116 c1ad14c551a9 2010-01-27:95:
|
||||
russellm 12116 c1ad14c551a9 2010-01-27:96: def clear(self):
|
||||
russellm 13275 4dd52d4f3f50 2010-08-05:136: db = router.db_for_write(self.cache_model_class)
|
||||
russellm 13275 4dd52d4f3f50 2010-08-05:137: table = connections[db].ops.quote_name(self._table)
|
||||
russellm 13275 4dd52d4f3f50 2010-08-05:138: cursor = connections[db].cursor()
|
||||
russellm 13275 4dd52d4f3f50 2010-08-05:139: cursor.execute('DELETE FROM %s' % table)
|
||||
russellm 14807 905c4a7e1f19 2010-12-21:143:
|
||||
russellm 14807 905c4a7e1f19 2010-12-21:144: # For backwards compatibility
|
||||
russellm 14807 905c4a7e1f19 2010-12-21:145: class CacheClass(DatabaseCache):
|
||||
russellm 14807 905c4a7e1f19 2010-12-21:146: pass
|
||||
@@ -0,0 +1,149 @@
|
||||
adrian 2287 3f0790d500a9 2006-02-24:1: "Database cache backend."
|
||||
jezdez 16338 bf038debb499 2011-07-13:2: import base64
|
||||
jezdez 16338 bf038debb499 2011-07-13:3: import time
|
||||
jezdez 16338 bf038debb499 2011-07-13:4: from datetime import datetime
|
||||
adrian 2287 3f0790d500a9 2006-02-24:2:
|
||||
adrian 2287 3f0790d500a9 2006-02-24:7: try:
|
||||
adrian 2287 3f0790d500a9 2006-02-24:8: import cPickle as pickle
|
||||
adrian 2287 3f0790d500a9 2006-02-24:9: except ImportError:
|
||||
adrian 2287 3f0790d500a9 2006-02-24:10: import pickle
|
||||
adrian 2287 3f0790d500a9 2006-02-24:11:
|
||||
jezdez 16338 bf038debb499 2011-07-13:11: from django.core.cache.backends.base import BaseCache
|
||||
jezdez 16338 bf038debb499 2011-07-13:12: from django.db import connections, router, transaction, DatabaseError
|
||||
jezdez 16338 bf038debb499 2011-07-13:13:
|
||||
jezdez 16338 bf038debb499 2011-07-13:14:
|
||||
russellm 13275 4dd52d4f3f50 2010-08-05:12: class Options(object):
|
||||
russellm 13275 4dd52d4f3f50 2010-08-05:13: """A class that will quack like a Django model _meta class.
|
||||
russellm 13275 4dd52d4f3f50 2010-08-05:14:
|
||||
russellm 13275 4dd52d4f3f50 2010-08-05:15: This allows cache operations to be controlled by the router
|
||||
russellm 13275 4dd52d4f3f50 2010-08-05:16: """
|
||||
russellm 13275 4dd52d4f3f50 2010-08-05:17: def __init__(self, table):
|
||||
russellm 13275 4dd52d4f3f50 2010-08-05:18: self.db_table = table
|
||||
russellm 13275 4dd52d4f3f50 2010-08-05:19: self.app_label = 'django_cache'
|
||||
russellm 13275 4dd52d4f3f50 2010-08-05:20: self.module_name = 'cacheentry'
|
||||
russellm 13275 4dd52d4f3f50 2010-08-05:21: self.verbose_name = 'cache entry'
|
||||
russellm 13275 4dd52d4f3f50 2010-08-05:22: self.verbose_name_plural = 'cache entries'
|
||||
russellm 13275 4dd52d4f3f50 2010-08-05:23: self.object_name = 'CacheEntry'
|
||||
russellm 13275 4dd52d4f3f50 2010-08-05:24: self.abstract = False
|
||||
russellm 13275 4dd52d4f3f50 2010-08-05:25: self.managed = True
|
||||
russellm 13275 4dd52d4f3f50 2010-08-05:26: self.proxy = False
|
||||
russellm 13275 4dd52d4f3f50 2010-08-05:27:
|
||||
russellm 14807 905c4a7e1f19 2010-12-21:28: class BaseDatabaseCache(BaseCache):
|
||||
russellm 14807 905c4a7e1f19 2010-12-21:29: def __init__(self, table, params):
|
||||
russellm 14807 905c4a7e1f19 2010-12-21:30: BaseCache.__init__(self, params)
|
||||
russellm 13275 4dd52d4f3f50 2010-08-05:31: self._table = table
|
||||
russellm 13275 4dd52d4f3f50 2010-08-05:32:
|
||||
russellm 13275 4dd52d4f3f50 2010-08-05:33: class CacheEntry(object):
|
||||
russellm 13275 4dd52d4f3f50 2010-08-05:34: _meta = Options(table)
|
||||
russellm 13275 4dd52d4f3f50 2010-08-05:35: self.cache_model_class = CacheEntry
|
||||
russellm 13275 4dd52d4f3f50 2010-08-05:36:
|
||||
russellm 14807 905c4a7e1f19 2010-12-21:37: class DatabaseCache(BaseDatabaseCache):
|
||||
russellm 14425 793e94ba2037 2010-11-19:38: def get(self, key, default=None, version=None):
|
||||
russellm 14425 793e94ba2037 2010-11-19:39: key = self.make_key(key, version=version)
|
||||
mtredinnick 13568 7e0b7bf098d2 2010-09-12:49: self.validate_key(key)
|
||||
russellm 13275 4dd52d4f3f50 2010-08-05:49: db = router.db_for_read(self.cache_model_class)
|
||||
russellm 13275 4dd52d4f3f50 2010-08-05:50: table = connections[db].ops.quote_name(self._table)
|
||||
russellm 13275 4dd52d4f3f50 2010-08-05:51: cursor = connections[db].cursor()
|
||||
russellm 13275 4dd52d4f3f50 2010-08-05:52:
|
||||
russellm 13275 4dd52d4f3f50 2010-08-05:53: cursor.execute("SELECT cache_key, value, expires FROM %s WHERE cache_key = %%s" % table, [key])
|
||||
adrian 2287 3f0790d500a9 2006-02-24:30: row = cursor.fetchone()
|
||||
adrian 2287 3f0790d500a9 2006-02-24:31: if row is None:
|
||||
adrian 2287 3f0790d500a9 2006-02-24:32: return default
|
||||
adrian 2287 3f0790d500a9 2006-02-24:33: now = datetime.now()
|
||||
adrian 2287 3f0790d500a9 2006-02-24:34: if row[2] < now:
|
||||
russellm 13275 4dd52d4f3f50 2010-08-05:59: db = router.db_for_write(self.cache_model_class)
|
||||
russellm 13275 4dd52d4f3f50 2010-08-05:60: cursor = connections[db].cursor()
|
||||
russellm 13275 4dd52d4f3f50 2010-08-05:61: cursor.execute("DELETE FROM %s WHERE cache_key = %%s" % table, [key])
|
||||
russellm 13275 4dd52d4f3f50 2010-08-05:62: transaction.commit_unless_managed(using=db)
|
||||
adrian 2287 3f0790d500a9 2006-02-24:37: return default
|
||||
russellm 13275 4dd52d4f3f50 2010-08-05:64: value = connections[db].ops.process_clob(row[1])
|
||||
ikelly 9862 8739c35149dd 2009-03-13:39: return pickle.loads(base64.decodestring(value))
|
||||
adrian 2287 3f0790d500a9 2006-02-24:39:
|
||||
russellm 14425 793e94ba2037 2010-11-19:59: def set(self, key, value, timeout=None, version=None):
|
||||
russellm 14425 793e94ba2037 2010-11-19:60: key = self.make_key(key, version=version)
|
||||
mtredinnick 13568 7e0b7bf098d2 2010-09-12:69: self.validate_key(key)
|
||||
mtredinnick 8110 c787c7f62142 2008-08-10:41: self._base_set('set', key, value, timeout)
|
||||
mtredinnick 6421 b4175804cc7b 2007-10-20:45:
|
||||
russellm 14425 793e94ba2037 2010-11-19:64: def add(self, key, value, timeout=None, version=None):
|
||||
russellm 14425 793e94ba2037 2010-11-19:65: key = self.make_key(key, version=version)
|
||||
mtredinnick 13568 7e0b7bf098d2 2010-09-12:73: self.validate_key(key)
|
||||
mtredinnick 6438 5096a56a9ac6 2007-10-21:44: return self._base_set('add', key, value, timeout)
|
||||
mtredinnick 6438 5096a56a9ac6 2007-10-21:45:
|
||||
mtredinnick 6421 b4175804cc7b 2007-10-20:46: def _base_set(self, mode, key, value, timeout=None):
|
||||
adrian 2287 3f0790d500a9 2006-02-24:41: if timeout is None:
|
||||
adrian 2287 3f0790d500a9 2006-02-24:42: timeout = self.default_timeout
|
||||
russellm 13275 4dd52d4f3f50 2010-08-05:76: db = router.db_for_write(self.cache_model_class)
|
||||
russellm 13275 4dd52d4f3f50 2010-08-05:77: table = connections[db].ops.quote_name(self._table)
|
||||
russellm 13275 4dd52d4f3f50 2010-08-05:78: cursor = connections[db].cursor()
|
||||
russellm 13275 4dd52d4f3f50 2010-08-05:79:
|
||||
russellm 13275 4dd52d4f3f50 2010-08-05:80: cursor.execute("SELECT COUNT(*) FROM %s" % table)
|
||||
adrian 2287 3f0790d500a9 2006-02-24:45: num = cursor.fetchone()[0]
|
||||
adrian 2287 3f0790d500a9 2006-02-24:46: now = datetime.now().replace(microsecond=0)
|
||||
adrian 2287 3f0790d500a9 2006-02-24:47: exp = datetime.fromtimestamp(time.time() + timeout).replace(microsecond=0)
|
||||
adrian 2287 3f0790d500a9 2006-02-24:48: if num > self._max_entries:
|
||||
russellm 13275 4dd52d4f3f50 2010-08-05:85: self._cull(db, cursor, now)
|
||||
adrian 2287 3f0790d500a9 2006-02-24:50: encoded = base64.encodestring(pickle.dumps(value, 2)).strip()
|
||||
russellm 13275 4dd52d4f3f50 2010-08-05:87: cursor.execute("SELECT cache_key, expires FROM %s WHERE cache_key = %%s" % table, [key])
|
||||
adrian 2287 3f0790d500a9 2006-02-24:52: try:
|
||||
mtredinnick 9753 0ab5ef23e1bc 2009-03-02:59: result = cursor.fetchone()
|
||||
mtredinnick 9753 0ab5ef23e1bc 2009-03-02:60: if result and (mode == 'set' or
|
||||
mtredinnick 9753 0ab5ef23e1bc 2009-03-02:61: (mode == 'add' and result[1] < now)):
|
||||
russellm 13275 4dd52d4f3f50 2010-08-05:92: cursor.execute("UPDATE %s SET value = %%s, expires = %%s WHERE cache_key = %%s" % table,
|
||||
russellm 13275 4dd52d4f3f50 2010-08-05:93: [encoded, connections[db].ops.value_to_db_datetime(exp), key])
|
||||
adrian 2287 3f0790d500a9 2006-02-24:55: else:
|
||||
russellm 13275 4dd52d4f3f50 2010-08-05:95: cursor.execute("INSERT INTO %s (cache_key, value, expires) VALUES (%%s, %%s, %%s)" % table,
|
||||
russellm 13275 4dd52d4f3f50 2010-08-05:96: [key, encoded, connections[db].ops.value_to_db_datetime(exp)])
|
||||
adrian 2287 3f0790d500a9 2006-02-24:57: except DatabaseError:
|
||||
adrian 2287 3f0790d500a9 2006-02-24:58: # To be threadsafe, updates/inserts are allowed to fail silently
|
||||
russellm 13275 4dd52d4f3f50 2010-08-05:99: transaction.rollback_unless_managed(using=db)
|
||||
mtredinnick 8110 c787c7f62142 2008-08-10:65: return False
|
||||
adrian 2287 3f0790d500a9 2006-02-24:60: else:
|
||||
russellm 13275 4dd52d4f3f50 2010-08-05:102: transaction.commit_unless_managed(using=db)
|
||||
mtredinnick 8110 c787c7f62142 2008-08-10:68: return True
|
||||
adrian 2287 3f0790d500a9 2006-02-24:62:
|
||||
russellm 14425 793e94ba2037 2010-11-19:101: def delete(self, key, version=None):
|
||||
russellm 14425 793e94ba2037 2010-11-19:102: key = self.make_key(key, version=version)
|
||||
mtredinnick 13568 7e0b7bf098d2 2010-09-12:109: self.validate_key(key)
|
||||
russellm 14425 793e94ba2037 2010-11-19:104:
|
||||
russellm 13275 4dd52d4f3f50 2010-08-05:106: db = router.db_for_write(self.cache_model_class)
|
||||
russellm 13275 4dd52d4f3f50 2010-08-05:107: table = connections[db].ops.quote_name(self._table)
|
||||
russellm 13275 4dd52d4f3f50 2010-08-05:108: cursor = connections[db].cursor()
|
||||
russellm 13275 4dd52d4f3f50 2010-08-05:109:
|
||||
russellm 13275 4dd52d4f3f50 2010-08-05:110: cursor.execute("DELETE FROM %s WHERE cache_key = %%s" % table, [key])
|
||||
russellm 13275 4dd52d4f3f50 2010-08-05:111: transaction.commit_unless_managed(using=db)
|
||||
adrian 2287 3f0790d500a9 2006-02-24:67:
|
||||
russellm 14425 793e94ba2037 2010-11-19:112: def has_key(self, key, version=None):
|
||||
russellm 14425 793e94ba2037 2010-11-19:113: key = self.make_key(key, version=version)
|
||||
mtredinnick 13568 7e0b7bf098d2 2010-09-12:118: self.validate_key(key)
|
||||
russellm 14425 793e94ba2037 2010-11-19:115:
|
||||
russellm 13275 4dd52d4f3f50 2010-08-05:114: db = router.db_for_read(self.cache_model_class)
|
||||
russellm 13275 4dd52d4f3f50 2010-08-05:115: table = connections[db].ops.quote_name(self._table)
|
||||
russellm 13275 4dd52d4f3f50 2010-08-05:116: cursor = connections[db].cursor()
|
||||
russellm 13275 4dd52d4f3f50 2010-08-05:117:
|
||||
mtredinnick 9753 0ab5ef23e1bc 2009-03-02:78: now = datetime.now().replace(microsecond=0)
|
||||
russellm 13275 4dd52d4f3f50 2010-08-05:119: cursor.execute("SELECT cache_key FROM %s WHERE cache_key = %%s and expires > %%s" % table,
|
||||
russellm 13275 4dd52d4f3f50 2010-08-05:120: [key, connections[db].ops.value_to_db_datetime(now)])
|
||||
adrian 2287 3f0790d500a9 2006-02-24:71: return cursor.fetchone() is not None
|
||||
adrian 2287 3f0790d500a9 2006-02-24:72:
|
||||
russellm 13275 4dd52d4f3f50 2010-08-05:123: def _cull(self, db, cursor, now):
|
||||
adrian 2287 3f0790d500a9 2006-02-24:74: if self._cull_frequency == 0:
|
||||
russellm 12116 c1ad14c551a9 2010-01-27:87: self.clear()
|
||||
adrian 2287 3f0790d500a9 2006-02-24:76: else:
|
||||
russellm 13480 7351411944a9 2010-08-31:127: table = connections[db].ops.quote_name(self._table)
|
||||
russellm 13275 4dd52d4f3f50 2010-08-05:127: cursor.execute("DELETE FROM %s WHERE expires < %%s" % table,
|
||||
russellm 13275 4dd52d4f3f50 2010-08-05:128: [connections[db].ops.value_to_db_datetime(now)])
|
||||
russellm 13275 4dd52d4f3f50 2010-08-05:129: cursor.execute("SELECT COUNT(*) FROM %s" % table)
|
||||
adrian 2287 3f0790d500a9 2006-02-24:79: num = cursor.fetchone()[0]
|
||||
adrian 2287 3f0790d500a9 2006-02-24:80: if num > self._max_entries:
|
||||
russellm 13275 4dd52d4f3f50 2010-08-05:132: cursor.execute("SELECT cache_key FROM %s ORDER BY cache_key LIMIT 1 OFFSET %%s" % table, [num / self._cull_frequency])
|
||||
russellm 13275 4dd52d4f3f50 2010-08-05:133: cursor.execute("DELETE FROM %s WHERE cache_key < %%s" % table, [cursor.fetchone()[0]])
|
||||
russellm 12116 c1ad14c551a9 2010-01-27:95:
|
||||
russellm 12116 c1ad14c551a9 2010-01-27:96: def clear(self):
|
||||
russellm 13275 4dd52d4f3f50 2010-08-05:136: db = router.db_for_write(self.cache_model_class)
|
||||
russellm 13275 4dd52d4f3f50 2010-08-05:137: table = connections[db].ops.quote_name(self._table)
|
||||
russellm 13275 4dd52d4f3f50 2010-08-05:138: cursor = connections[db].cursor()
|
||||
russellm 13275 4dd52d4f3f50 2010-08-05:139: cursor.execute('DELETE FROM %s' % table)
|
||||
russellm 14807 905c4a7e1f19 2010-12-21:143:
|
||||
russellm 14807 905c4a7e1f19 2010-12-21:144: # For backwards compatibility
|
||||
russellm 14807 905c4a7e1f19 2010-12-21:145: class CacheClass(DatabaseCache):
|
||||
russellm 14807 905c4a7e1f19 2010-12-21:146: pass
|
||||
@@ -0,0 +1,149 @@
|
||||
adrian 2287 3f0790d500a9 2006-02-24: 1: "Database cache backend."
|
||||
jezdez 16338 bf038debb499 2011-07-13: 2: import base64
|
||||
jezdez 16338 bf038debb499 2011-07-13: 3: import time
|
||||
jezdez 16338 bf038debb499 2011-07-13: 4: from datetime import datetime
|
||||
adrian 2287 3f0790d500a9 2006-02-24: 2:
|
||||
adrian 2287 3f0790d500a9 2006-02-24: 7: try:
|
||||
adrian 2287 3f0790d500a9 2006-02-24: 8: import cPickle as pickle
|
||||
adrian 2287 3f0790d500a9 2006-02-24: 9: except ImportError:
|
||||
adrian 2287 3f0790d500a9 2006-02-24: 10: import pickle
|
||||
adrian 2287 3f0790d500a9 2006-02-24: 11:
|
||||
jezdez 16338 bf038debb499 2011-07-13: 11: from django.core.cache.backends.base import BaseCache
|
||||
jezdez 16338 bf038debb499 2011-07-13: 12: from django.db import connections, router, transaction, DatabaseError
|
||||
jezdez 16338 bf038debb499 2011-07-13: 13:
|
||||
jezdez 16338 bf038debb499 2011-07-13: 14:
|
||||
russellm 13275 4dd52d4f3f50 2010-08-05: 12: class Options(object):
|
||||
russellm 13275 4dd52d4f3f50 2010-08-05: 13: """A class that will quack like a Django model _meta class.
|
||||
russellm 13275 4dd52d4f3f50 2010-08-05: 14:
|
||||
russellm 13275 4dd52d4f3f50 2010-08-05: 15: This allows cache operations to be controlled by the router
|
||||
russellm 13275 4dd52d4f3f50 2010-08-05: 16: """
|
||||
russellm 13275 4dd52d4f3f50 2010-08-05: 17: def __init__(self, table):
|
||||
russellm 13275 4dd52d4f3f50 2010-08-05: 18: self.db_table = table
|
||||
russellm 13275 4dd52d4f3f50 2010-08-05: 19: self.app_label = 'django_cache'
|
||||
russellm 13275 4dd52d4f3f50 2010-08-05: 20: self.module_name = 'cacheentry'
|
||||
russellm 13275 4dd52d4f3f50 2010-08-05: 21: self.verbose_name = 'cache entry'
|
||||
russellm 13275 4dd52d4f3f50 2010-08-05: 22: self.verbose_name_plural = 'cache entries'
|
||||
russellm 13275 4dd52d4f3f50 2010-08-05: 23: self.object_name = 'CacheEntry'
|
||||
russellm 13275 4dd52d4f3f50 2010-08-05: 24: self.abstract = False
|
||||
russellm 13275 4dd52d4f3f50 2010-08-05: 25: self.managed = True
|
||||
russellm 13275 4dd52d4f3f50 2010-08-05: 26: self.proxy = False
|
||||
russellm 13275 4dd52d4f3f50 2010-08-05: 27:
|
||||
russellm 14807 905c4a7e1f19 2010-12-21: 28: class BaseDatabaseCache(BaseCache):
|
||||
russellm 14807 905c4a7e1f19 2010-12-21: 29: def __init__(self, table, params):
|
||||
russellm 14807 905c4a7e1f19 2010-12-21: 30: BaseCache.__init__(self, params)
|
||||
russellm 13275 4dd52d4f3f50 2010-08-05: 31: self._table = table
|
||||
russellm 13275 4dd52d4f3f50 2010-08-05: 32:
|
||||
russellm 13275 4dd52d4f3f50 2010-08-05: 33: class CacheEntry(object):
|
||||
russellm 13275 4dd52d4f3f50 2010-08-05: 34: _meta = Options(table)
|
||||
russellm 13275 4dd52d4f3f50 2010-08-05: 35: self.cache_model_class = CacheEntry
|
||||
russellm 13275 4dd52d4f3f50 2010-08-05: 36:
|
||||
russellm 14807 905c4a7e1f19 2010-12-21: 37: class DatabaseCache(BaseDatabaseCache):
|
||||
russellm 14425 793e94ba2037 2010-11-19: 38: def get(self, key, default=None, version=None):
|
||||
russellm 14425 793e94ba2037 2010-11-19: 39: key = self.make_key(key, version=version)
|
||||
mtredinnick 13568 7e0b7bf098d2 2010-09-12: 49: self.validate_key(key)
|
||||
russellm 13275 4dd52d4f3f50 2010-08-05: 49: db = router.db_for_read(self.cache_model_class)
|
||||
russellm 13275 4dd52d4f3f50 2010-08-05: 50: table = connections[db].ops.quote_name(self._table)
|
||||
russellm 13275 4dd52d4f3f50 2010-08-05: 51: cursor = connections[db].cursor()
|
||||
russellm 13275 4dd52d4f3f50 2010-08-05: 52:
|
||||
russellm 13275 4dd52d4f3f50 2010-08-05: 53: cursor.execute("SELECT cache_key, value, expires FROM %s WHERE cache_key = %%s" % table, [key])
|
||||
adrian 2287 3f0790d500a9 2006-02-24: 30: row = cursor.fetchone()
|
||||
adrian 2287 3f0790d500a9 2006-02-24: 31: if row is None:
|
||||
adrian 2287 3f0790d500a9 2006-02-24: 32: return default
|
||||
adrian 2287 3f0790d500a9 2006-02-24: 33: now = datetime.now()
|
||||
adrian 2287 3f0790d500a9 2006-02-24: 34: if row[2] < now:
|
||||
russellm 13275 4dd52d4f3f50 2010-08-05: 59: db = router.db_for_write(self.cache_model_class)
|
||||
russellm 13275 4dd52d4f3f50 2010-08-05: 60: cursor = connections[db].cursor()
|
||||
russellm 13275 4dd52d4f3f50 2010-08-05: 61: cursor.execute("DELETE FROM %s WHERE cache_key = %%s" % table, [key])
|
||||
russellm 13275 4dd52d4f3f50 2010-08-05: 62: transaction.commit_unless_managed(using=db)
|
||||
adrian 2287 3f0790d500a9 2006-02-24: 37: return default
|
||||
russellm 13275 4dd52d4f3f50 2010-08-05: 64: value = connections[db].ops.process_clob(row[1])
|
||||
ikelly 9862 8739c35149dd 2009-03-13: 39: return pickle.loads(base64.decodestring(value))
|
||||
adrian 2287 3f0790d500a9 2006-02-24: 39:
|
||||
russellm 14425 793e94ba2037 2010-11-19: 59: def set(self, key, value, timeout=None, version=None):
|
||||
russellm 14425 793e94ba2037 2010-11-19: 60: key = self.make_key(key, version=version)
|
||||
mtredinnick 13568 7e0b7bf098d2 2010-09-12: 69: self.validate_key(key)
|
||||
mtredinnick 8110 c787c7f62142 2008-08-10: 41: self._base_set('set', key, value, timeout)
|
||||
mtredinnick 6421 b4175804cc7b 2007-10-20: 45:
|
||||
russellm 14425 793e94ba2037 2010-11-19: 64: def add(self, key, value, timeout=None, version=None):
|
||||
russellm 14425 793e94ba2037 2010-11-19: 65: key = self.make_key(key, version=version)
|
||||
mtredinnick 13568 7e0b7bf098d2 2010-09-12: 73: self.validate_key(key)
|
||||
mtredinnick 6438 5096a56a9ac6 2007-10-21: 44: return self._base_set('add', key, value, timeout)
|
||||
mtredinnick 6438 5096a56a9ac6 2007-10-21: 45:
|
||||
mtredinnick 6421 b4175804cc7b 2007-10-20: 46: def _base_set(self, mode, key, value, timeout=None):
|
||||
adrian 2287 3f0790d500a9 2006-02-24: 41: if timeout is None:
|
||||
adrian 2287 3f0790d500a9 2006-02-24: 42: timeout = self.default_timeout
|
||||
russellm 13275 4dd52d4f3f50 2010-08-05: 76: db = router.db_for_write(self.cache_model_class)
|
||||
russellm 13275 4dd52d4f3f50 2010-08-05: 77: table = connections[db].ops.quote_name(self._table)
|
||||
russellm 13275 4dd52d4f3f50 2010-08-05: 78: cursor = connections[db].cursor()
|
||||
russellm 13275 4dd52d4f3f50 2010-08-05: 79:
|
||||
russellm 13275 4dd52d4f3f50 2010-08-05: 80: cursor.execute("SELECT COUNT(*) FROM %s" % table)
|
||||
adrian 2287 3f0790d500a9 2006-02-24: 45: num = cursor.fetchone()[0]
|
||||
adrian 2287 3f0790d500a9 2006-02-24: 46: now = datetime.now().replace(microsecond=0)
|
||||
adrian 2287 3f0790d500a9 2006-02-24: 47: exp = datetime.fromtimestamp(time.time() + timeout).replace(microsecond=0)
|
||||
adrian 2287 3f0790d500a9 2006-02-24: 48: if num > self._max_entries:
|
||||
russellm 13275 4dd52d4f3f50 2010-08-05: 85: self._cull(db, cursor, now)
|
||||
adrian 2287 3f0790d500a9 2006-02-24: 50: encoded = base64.encodestring(pickle.dumps(value, 2)).strip()
|
||||
russellm 13275 4dd52d4f3f50 2010-08-05: 87: cursor.execute("SELECT cache_key, expires FROM %s WHERE cache_key = %%s" % table, [key])
|
||||
adrian 2287 3f0790d500a9 2006-02-24: 52: try:
|
||||
mtredinnick 9753 0ab5ef23e1bc 2009-03-02: 59: result = cursor.fetchone()
|
||||
mtredinnick 9753 0ab5ef23e1bc 2009-03-02: 60: if result and (mode == 'set' or
|
||||
mtredinnick 9753 0ab5ef23e1bc 2009-03-02: 61: (mode == 'add' and result[1] < now)):
|
||||
russellm 13275 4dd52d4f3f50 2010-08-05: 92: cursor.execute("UPDATE %s SET value = %%s, expires = %%s WHERE cache_key = %%s" % table,
|
||||
russellm 13275 4dd52d4f3f50 2010-08-05: 93: [encoded, connections[db].ops.value_to_db_datetime(exp), key])
|
||||
adrian 2287 3f0790d500a9 2006-02-24: 55: else:
|
||||
russellm 13275 4dd52d4f3f50 2010-08-05: 95: cursor.execute("INSERT INTO %s (cache_key, value, expires) VALUES (%%s, %%s, %%s)" % table,
|
||||
russellm 13275 4dd52d4f3f50 2010-08-05: 96: [key, encoded, connections[db].ops.value_to_db_datetime(exp)])
|
||||
adrian 2287 3f0790d500a9 2006-02-24: 57: except DatabaseError:
|
||||
adrian 2287 3f0790d500a9 2006-02-24: 58: # To be threadsafe, updates/inserts are allowed to fail silently
|
||||
russellm 13275 4dd52d4f3f50 2010-08-05: 99: transaction.rollback_unless_managed(using=db)
|
||||
mtredinnick 8110 c787c7f62142 2008-08-10: 65: return False
|
||||
adrian 2287 3f0790d500a9 2006-02-24: 60: else:
|
||||
russellm 13275 4dd52d4f3f50 2010-08-05:102: transaction.commit_unless_managed(using=db)
|
||||
mtredinnick 8110 c787c7f62142 2008-08-10: 68: return True
|
||||
adrian 2287 3f0790d500a9 2006-02-24: 62:
|
||||
russellm 14425 793e94ba2037 2010-11-19:101: def delete(self, key, version=None):
|
||||
russellm 14425 793e94ba2037 2010-11-19:102: key = self.make_key(key, version=version)
|
||||
mtredinnick 13568 7e0b7bf098d2 2010-09-12:109: self.validate_key(key)
|
||||
russellm 14425 793e94ba2037 2010-11-19:104:
|
||||
russellm 13275 4dd52d4f3f50 2010-08-05:106: db = router.db_for_write(self.cache_model_class)
|
||||
russellm 13275 4dd52d4f3f50 2010-08-05:107: table = connections[db].ops.quote_name(self._table)
|
||||
russellm 13275 4dd52d4f3f50 2010-08-05:108: cursor = connections[db].cursor()
|
||||
russellm 13275 4dd52d4f3f50 2010-08-05:109:
|
||||
russellm 13275 4dd52d4f3f50 2010-08-05:110: cursor.execute("DELETE FROM %s WHERE cache_key = %%s" % table, [key])
|
||||
russellm 13275 4dd52d4f3f50 2010-08-05:111: transaction.commit_unless_managed(using=db)
|
||||
adrian 2287 3f0790d500a9 2006-02-24: 67:
|
||||
russellm 14425 793e94ba2037 2010-11-19:112: def has_key(self, key, version=None):
|
||||
russellm 14425 793e94ba2037 2010-11-19:113: key = self.make_key(key, version=version)
|
||||
mtredinnick 13568 7e0b7bf098d2 2010-09-12:118: self.validate_key(key)
|
||||
russellm 14425 793e94ba2037 2010-11-19:115:
|
||||
russellm 13275 4dd52d4f3f50 2010-08-05:114: db = router.db_for_read(self.cache_model_class)
|
||||
russellm 13275 4dd52d4f3f50 2010-08-05:115: table = connections[db].ops.quote_name(self._table)
|
||||
russellm 13275 4dd52d4f3f50 2010-08-05:116: cursor = connections[db].cursor()
|
||||
russellm 13275 4dd52d4f3f50 2010-08-05:117:
|
||||
mtredinnick 9753 0ab5ef23e1bc 2009-03-02: 78: now = datetime.now().replace(microsecond=0)
|
||||
russellm 13275 4dd52d4f3f50 2010-08-05:119: cursor.execute("SELECT cache_key FROM %s WHERE cache_key = %%s and expires > %%s" % table,
|
||||
russellm 13275 4dd52d4f3f50 2010-08-05:120: [key, connections[db].ops.value_to_db_datetime(now)])
|
||||
adrian 2287 3f0790d500a9 2006-02-24: 71: return cursor.fetchone() is not None
|
||||
adrian 2287 3f0790d500a9 2006-02-24: 72:
|
||||
russellm 13275 4dd52d4f3f50 2010-08-05:123: def _cull(self, db, cursor, now):
|
||||
adrian 2287 3f0790d500a9 2006-02-24: 74: if self._cull_frequency == 0:
|
||||
russellm 12116 c1ad14c551a9 2010-01-27: 87: self.clear()
|
||||
adrian 2287 3f0790d500a9 2006-02-24: 76: else:
|
||||
russellm 13480 7351411944a9 2010-08-31:127: table = connections[db].ops.quote_name(self._table)
|
||||
russellm 13275 4dd52d4f3f50 2010-08-05:127: cursor.execute("DELETE FROM %s WHERE expires < %%s" % table,
|
||||
russellm 13275 4dd52d4f3f50 2010-08-05:128: [connections[db].ops.value_to_db_datetime(now)])
|
||||
russellm 13275 4dd52d4f3f50 2010-08-05:129: cursor.execute("SELECT COUNT(*) FROM %s" % table)
|
||||
adrian 2287 3f0790d500a9 2006-02-24: 79: num = cursor.fetchone()[0]
|
||||
adrian 2287 3f0790d500a9 2006-02-24: 80: if num > self._max_entries:
|
||||
russellm 13275 4dd52d4f3f50 2010-08-05:132: cursor.execute("SELECT cache_key FROM %s ORDER BY cache_key LIMIT 1 OFFSET %%s" % table, [num / self._cull_frequency])
|
||||
russellm 13275 4dd52d4f3f50 2010-08-05:133: cursor.execute("DELETE FROM %s WHERE cache_key < %%s" % table, [cursor.fetchone()[0]])
|
||||
russellm 12116 c1ad14c551a9 2010-01-27: 95:
|
||||
russellm 12116 c1ad14c551a9 2010-01-27: 96: def clear(self):
|
||||
russellm 13275 4dd52d4f3f50 2010-08-05:136: db = router.db_for_write(self.cache_model_class)
|
||||
russellm 13275 4dd52d4f3f50 2010-08-05:137: table = connections[db].ops.quote_name(self._table)
|
||||
russellm 13275 4dd52d4f3f50 2010-08-05:138: cursor = connections[db].cursor()
|
||||
russellm 13275 4dd52d4f3f50 2010-08-05:139: cursor.execute('DELETE FROM %s' % table)
|
||||
russellm 14807 905c4a7e1f19 2010-12-21:143:
|
||||
russellm 14807 905c4a7e1f19 2010-12-21:144: # For backwards compatibility
|
||||
russellm 14807 905c4a7e1f19 2010-12-21:145: class CacheClass(DatabaseCache):
|
||||
russellm 14807 905c4a7e1f19 2010-12-21:146: pass
|
||||
@@ -0,0 +1,139 @@
|
||||
/*
|
||||
* Copyright 2000-2011 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.zmlx.hg4idea.test;
|
||||
|
||||
import com.intellij.openapi.application.PluginPathManager;
|
||||
import com.intellij.openapi.util.io.FileUtil;
|
||||
import com.thoughtworks.xstream.XStream;
|
||||
import org.testng.annotations.BeforeClass;
|
||||
import org.testng.annotations.BeforeMethod;
|
||||
import org.testng.annotations.DataProvider;
|
||||
import org.testng.annotations.Test;
|
||||
import org.zmlx.hg4idea.HgRevisionNumber;
|
||||
import org.zmlx.hg4idea.HgVcs;
|
||||
import org.zmlx.hg4idea.command.HgAnnotateCommand;
|
||||
import org.zmlx.hg4idea.provider.annotate.HgAnnotationLine;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileReader;
|
||||
import java.io.FileWriter;
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import static org.testng.Assert.assertEquals;
|
||||
import static org.testng.Assert.fail;
|
||||
|
||||
/**
|
||||
* @author Kirill Likhodedov
|
||||
*/
|
||||
public class HgAnnotateCommandTest extends HgSingleUserTest {
|
||||
|
||||
private File myPluginRoot;
|
||||
private File myAnnotateDataDir;
|
||||
private File myOutputsDir;
|
||||
private List<HgAnnotationLine> myAnnotations;
|
||||
|
||||
@BeforeMethod
|
||||
@Override
|
||||
protected void setUp() throws Exception {
|
||||
super.setUp();
|
||||
}
|
||||
|
||||
@BeforeClass
|
||||
private void loadEthalonAnnotations() throws IOException {
|
||||
myPluginRoot = new File(PluginPathManager.getPluginHomePath(HgVcs.VCS_NAME));
|
||||
myAnnotateDataDir = new File(myPluginRoot, "testData/annotate");
|
||||
myOutputsDir = new File(myAnnotateDataDir, "outputs");
|
||||
|
||||
final File etalonFile = new File(myAnnotateDataDir, "etalon");
|
||||
|
||||
XStream xStream = new XStream();
|
||||
FileReader reader = new FileReader(etalonFile);
|
||||
try {
|
||||
myAnnotations = (List<HgAnnotationLine>) xStream.fromXML(reader);
|
||||
}
|
||||
finally {
|
||||
reader.close();
|
||||
}
|
||||
}
|
||||
|
||||
@DataProvider(name = "annotate_output")
|
||||
public Object[][] createValidData() throws IOException {
|
||||
Object[][] data = new Object[myOutputsDir.listFiles().length][];
|
||||
for (int i = 0; i < myOutputsDir.listFiles().length; i++) {
|
||||
File annotateData = myOutputsDir.listFiles()[i];
|
||||
String fileText = FileUtil.loadFile(annotateData);
|
||||
data[i] = new String[] {annotateData.getName(), fileText};
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
||||
@Test(dataProvider = "annotate_output")
|
||||
public void testParse(String fileName, String annotationNativeOutput)
|
||||
throws NoSuchMethodException, InvocationTargetException, IllegalAccessException
|
||||
{
|
||||
HgAnnotateCommand command = new HgAnnotateCommand(myProject);
|
||||
Method parseMethod = HgAnnotateCommand.class.getDeclaredMethod("parse", List.class);
|
||||
parseMethod.setAccessible(true);
|
||||
|
||||
List<String> annotations = Arrays.asList(annotationNativeOutput.split("(\n|\r|\r\n)"));
|
||||
List<HgAnnotationLine> result = (List<HgAnnotationLine>)parseMethod.invoke(command, annotations);
|
||||
assertEquals(result, myAnnotations);
|
||||
}
|
||||
|
||||
//@Test
|
||||
public void generateCorrectAnnotation() throws IOException {
|
||||
final File etalonFile = new File(myAnnotateDataDir, "etalon");
|
||||
|
||||
File outputFile = new File(myOutputsDir, "hg_1.9.0");
|
||||
String output = FileUtil.loadFile(outputFile);
|
||||
String[] split = output.split("(\n|\r|\r\n)");
|
||||
List<HgAnnotationLine> annotationLines = new ArrayList<HgAnnotationLine>(split.length);
|
||||
|
||||
Pattern pattern = Pattern.compile("\\s*(.+)\\s+(\\d+)\\s+([a-fA-F0-9]+)\\s+(\\d{4}-\\d{2}-\\d{2}):\\s*(\\d+): ?(.*)");
|
||||
for (String line : split) {
|
||||
Matcher matcher = pattern.matcher(line);
|
||||
if (!matcher.matches()) {
|
||||
fail("Couldn't parse line [ " + line + " ]");
|
||||
}
|
||||
String user = matcher.group(1);
|
||||
String shortRev = matcher.group(2);
|
||||
String fullRev = matcher.group(3);
|
||||
String date = matcher.group(4);
|
||||
String lineNum = matcher.group(5);
|
||||
String content = matcher.group(6);
|
||||
annotationLines
|
||||
.add(new HgAnnotationLine(user, HgRevisionNumber.getInstance(shortRev, fullRev), date, Integer.parseInt(lineNum), content));
|
||||
}
|
||||
|
||||
XStream xStream = new XStream();
|
||||
FileWriter writer = new FileWriter(etalonFile);
|
||||
try {
|
||||
xStream.toXML(annotationLines, writer);
|
||||
}
|
||||
finally {
|
||||
writer.close();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user