From 8c0bf64c96e3cf19e236089ecd8cef170ae5865b Mon Sep 17 00:00:00 2001 From: Kirill Likhodedov Date: Fri, 19 Aug 2011 15:56:54 +0400 Subject: [PATCH] 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] --- .../hg4idea/command/HgAnnotateCommand.java | 20 +- .../provider/annotate/HgAnnotationLine.java | 16 + plugins/hg4idea/testData/annotate/etalon | 4621 +++++++++++++++++ plugins/hg4idea/testData/annotate/info.txt | 3 + .../testData/annotate/outputs/hg_1.7.1 | 149 + .../testData/annotate/outputs/hg_1.8.2 | 149 + .../testData/annotate/outputs/hg_1.9.0 | 149 + .../hg4idea/test/HgAnnotateCommandTest.java | 139 + 8 files changed, 5239 insertions(+), 7 deletions(-) create mode 100644 plugins/hg4idea/testData/annotate/etalon create mode 100644 plugins/hg4idea/testData/annotate/info.txt create mode 100644 plugins/hg4idea/testData/annotate/outputs/hg_1.7.1 create mode 100644 plugins/hg4idea/testData/annotate/outputs/hg_1.8.2 create mode 100644 plugins/hg4idea/testData/annotate/outputs/hg_1.9.0 create mode 100644 plugins/hg4idea/testSrc/org/zmlx/hg4idea/test/HgAnnotateCommandTest.java diff --git a/plugins/hg4idea/src/org/zmlx/hg4idea/command/HgAnnotateCommand.java b/plugins/hg4idea/src/org/zmlx/hg4idea/command/HgAnnotateCommand.java index 6fc4bbd22f01..879c6f0428b0 100644 --- a/plugins/hg4idea/src/org/zmlx/hg4idea/command/HgAnnotateCommand.java +++ b/plugins/hg4idea/src/org/zmlx/hg4idea/command/HgAnnotateCommand.java @@ -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 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 annotations = new ArrayList(); if (result == null) { - return annotations; + return Collections.emptyList(); } - for (String line : result.getOutputLines()) { + List outputLines = result.getOutputLines(); + return parse(outputLines); + } + + private static List parse(List outputLines) { + List annotations = new ArrayList(outputLines.size()); + for (String line : outputLines) { Matcher matcher = LINE_PATTERN.matcher(line); if (matcher.matches()) { String user = matcher.group(USER_GROUP); diff --git a/plugins/hg4idea/src/org/zmlx/hg4idea/provider/annotate/HgAnnotationLine.java b/plugins/hg4idea/src/org/zmlx/hg4idea/provider/annotate/HgAnnotationLine.java index 939f0fa359b2..1eb3064dbc8c 100644 --- a/plugins/hg4idea/src/org/zmlx/hg4idea/provider/annotate/HgAnnotationLine.java +++ b/plugins/hg4idea/src/org/zmlx/hg4idea/provider/annotate/HgAnnotationLine.java @@ -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(); + } } diff --git a/plugins/hg4idea/testData/annotate/etalon b/plugins/hg4idea/testData/annotate/etalon new file mode 100644 index 000000000000..352a6064087d --- /dev/null +++ b/plugins/hg4idea/testData/annotate/etalon @@ -0,0 +1,4621 @@ + + + + + USER + adrian + + + REVISION + + 2287 + 3f0790d500a9 + + + + false + + + + DATE + 2006-02-24 + + + LINE + 1 + + + CONTENT + "Database cache backend." + + + + + + + + jezdez + + + + + 16338 + bf038debb499 + + + + false + + + + + 2011-07-13 + + + + 2 + + + + import base64 + + + + + + + + jezdez + + + + + 16338 + bf038debb499 + + + + false + + + + + 2011-07-13 + + + + 3 + + + + import time + + + + + + + + jezdez + + + + + 16338 + bf038debb499 + + + + false + + + + + 2011-07-13 + + + + 4 + + + + from datetime import datetime + + + + + + + + adrian + + + + + 2287 + 3f0790d500a9 + + + + false + + + + + 2006-02-24 + + + + 2 + + + + + + + + + + + + adrian + + + + + 2287 + 3f0790d500a9 + + + + false + + + + + 2006-02-24 + + + + 7 + + + + try: + + + + + + + + adrian + + + + + 2287 + 3f0790d500a9 + + + + false + + + + + 2006-02-24 + + + + 8 + + + + import cPickle as pickle + + + + + + + + adrian + + + + + 2287 + 3f0790d500a9 + + + + false + + + + + 2006-02-24 + + + + 9 + + + + except ImportError: + + + + + + + + adrian + + + + + 2287 + 3f0790d500a9 + + + + false + + + + + 2006-02-24 + + + + 10 + + + + import pickle + + + + + + + + adrian + + + + + 2287 + 3f0790d500a9 + + + + false + + + + + 2006-02-24 + + + + 11 + + + + + + + + + + + + jezdez + + + + + 16338 + bf038debb499 + + + + false + + + + + 2011-07-13 + + + + 11 + + + + from django.core.cache.backends.base import BaseCache + + + + + + + + jezdez + + + + + 16338 + bf038debb499 + + + + false + + + + + 2011-07-13 + + + + 12 + + + + from django.db import connections, router, transaction, DatabaseError + + + + + + + + jezdez + + + + + 16338 + bf038debb499 + + + + false + + + + + 2011-07-13 + + + + 13 + + + + + + + + + + + + jezdez + + + + + 16338 + bf038debb499 + + + + false + + + + + 2011-07-13 + + + + 14 + + + + + + + + + + + + russellm + + + + + 13275 + 4dd52d4f3f50 + + + + false + + + + + 2010-08-05 + + + + 12 + + + + class Options(object): + + + + + + + + russellm + + + + + 13275 + 4dd52d4f3f50 + + + + false + + + + + 2010-08-05 + + + + 13 + + + + """A class that will quack like a Django model _meta class. + + + + + + + + russellm + + + + + 13275 + 4dd52d4f3f50 + + + + false + + + + + 2010-08-05 + + + + 14 + + + + + + + + + + + + russellm + + + + + 13275 + 4dd52d4f3f50 + + + + false + + + + + 2010-08-05 + + + + 15 + + + + This allows cache operations to be controlled by the router + + + + + + + + russellm + + + + + 13275 + 4dd52d4f3f50 + + + + false + + + + + 2010-08-05 + + + + 16 + + + + """ + + + + + + + + russellm + + + + + 13275 + 4dd52d4f3f50 + + + + false + + + + + 2010-08-05 + + + + 17 + + + + def __init__(self, table): + + + + + + + + russellm + + + + + 13275 + 4dd52d4f3f50 + + + + false + + + + + 2010-08-05 + + + + 18 + + + + self.db_table = table + + + + + + + + russellm + + + + + 13275 + 4dd52d4f3f50 + + + + false + + + + + 2010-08-05 + + + + 19 + + + + self.app_label = 'django_cache' + + + + + + + + russellm + + + + + 13275 + 4dd52d4f3f50 + + + + false + + + + + 2010-08-05 + + + + 20 + + + + self.module_name = 'cacheentry' + + + + + + + + russellm + + + + + 13275 + 4dd52d4f3f50 + + + + false + + + + + 2010-08-05 + + + + 21 + + + + self.verbose_name = 'cache entry' + + + + + + + + russellm + + + + + 13275 + 4dd52d4f3f50 + + + + false + + + + + 2010-08-05 + + + + 22 + + + + self.verbose_name_plural = 'cache entries' + + + + + + + + russellm + + + + + 13275 + 4dd52d4f3f50 + + + + false + + + + + 2010-08-05 + + + + 23 + + + + self.object_name = 'CacheEntry' + + + + + + + + russellm + + + + + 13275 + 4dd52d4f3f50 + + + + false + + + + + 2010-08-05 + + + + 24 + + + + self.abstract = False + + + + + + + + russellm + + + + + 13275 + 4dd52d4f3f50 + + + + false + + + + + 2010-08-05 + + + + 25 + + + + self.managed = True + + + + + + + + russellm + + + + + 13275 + 4dd52d4f3f50 + + + + false + + + + + 2010-08-05 + + + + 26 + + + + self.proxy = False + + + + + + + + russellm + + + + + 13275 + 4dd52d4f3f50 + + + + false + + + + + 2010-08-05 + + + + 27 + + + + + + + + + + + + russellm + + + + + 14807 + 905c4a7e1f19 + + + + false + + + + + 2010-12-21 + + + + 28 + + + + class BaseDatabaseCache(BaseCache): + + + + + + + + russellm + + + + + 14807 + 905c4a7e1f19 + + + + false + + + + + 2010-12-21 + + + + 29 + + + + def __init__(self, table, params): + + + + + + + + russellm + + + + + 14807 + 905c4a7e1f19 + + + + false + + + + + 2010-12-21 + + + + 30 + + + + BaseCache.__init__(self, params) + + + + + + + + russellm + + + + + 13275 + 4dd52d4f3f50 + + + + false + + + + + 2010-08-05 + + + + 31 + + + + self._table = table + + + + + + + + russellm + + + + + 13275 + 4dd52d4f3f50 + + + + false + + + + + 2010-08-05 + + + + 32 + + + + + + + + + + + + russellm + + + + + 13275 + 4dd52d4f3f50 + + + + false + + + + + 2010-08-05 + + + + 33 + + + + class CacheEntry(object): + + + + + + + + russellm + + + + + 13275 + 4dd52d4f3f50 + + + + false + + + + + 2010-08-05 + + + + 34 + + + + _meta = Options(table) + + + + + + + + russellm + + + + + 13275 + 4dd52d4f3f50 + + + + false + + + + + 2010-08-05 + + + + 35 + + + + self.cache_model_class = CacheEntry + + + + + + + + russellm + + + + + 13275 + 4dd52d4f3f50 + + + + false + + + + + 2010-08-05 + + + + 36 + + + + + + + + + + + + russellm + + + + + 14807 + 905c4a7e1f19 + + + + false + + + + + 2010-12-21 + + + + 37 + + + + class DatabaseCache(BaseDatabaseCache): + + + + + + + + russellm + + + + + 14425 + 793e94ba2037 + + + + false + + + + + 2010-11-19 + + + + 38 + + + + def get(self, key, default=None, version=None): + + + + + + + + russellm + + + + + 14425 + 793e94ba2037 + + + + false + + + + + 2010-11-19 + + + + 39 + + + + key = self.make_key(key, version=version) + + + + + + + + mtredinnick + + + + + 13568 + 7e0b7bf098d2 + + + + false + + + + + 2010-09-12 + + + + 49 + + + + self.validate_key(key) + + + + + + + + russellm + + + + + 13275 + 4dd52d4f3f50 + + + + false + + + + + 2010-08-05 + + + + 49 + + + + db = router.db_for_read(self.cache_model_class) + + + + + + + + russellm + + + + + 13275 + 4dd52d4f3f50 + + + + false + + + + + 2010-08-05 + + + + 50 + + + + table = connections[db].ops.quote_name(self._table) + + + + + + + + russellm + + + + + 13275 + 4dd52d4f3f50 + + + + false + + + + + 2010-08-05 + + + + 51 + + + + cursor = connections[db].cursor() + + + + + + + + russellm + + + + + 13275 + 4dd52d4f3f50 + + + + false + + + + + 2010-08-05 + + + + 52 + + + + + + + + + + + + russellm + + + + + 13275 + 4dd52d4f3f50 + + + + false + + + + + 2010-08-05 + + + + 53 + + + + cursor.execute("SELECT cache_key, value, expires FROM %s WHERE cache_key = %%s" % table, [key]) + + + + + + + + adrian + + + + + 2287 + 3f0790d500a9 + + + + false + + + + + 2006-02-24 + + + + 30 + + + + row = cursor.fetchone() + + + + + + + + adrian + + + + + 2287 + 3f0790d500a9 + + + + false + + + + + 2006-02-24 + + + + 31 + + + + if row is None: + + + + + + + + adrian + + + + + 2287 + 3f0790d500a9 + + + + false + + + + + 2006-02-24 + + + + 32 + + + + return default + + + + + + + + adrian + + + + + 2287 + 3f0790d500a9 + + + + false + + + + + 2006-02-24 + + + + 33 + + + + now = datetime.now() + + + + + + + + adrian + + + + + 2287 + 3f0790d500a9 + + + + false + + + + + 2006-02-24 + + + + 34 + + + + if row[2] < now: + + + + + + + + russellm + + + + + 13275 + 4dd52d4f3f50 + + + + false + + + + + 2010-08-05 + + + + 59 + + + + db = router.db_for_write(self.cache_model_class) + + + + + + + + russellm + + + + + 13275 + 4dd52d4f3f50 + + + + false + + + + + 2010-08-05 + + + + 60 + + + + cursor = connections[db].cursor() + + + + + + + + russellm + + + + + 13275 + 4dd52d4f3f50 + + + + false + + + + + 2010-08-05 + + + + 61 + + + + cursor.execute("DELETE FROM %s WHERE cache_key = %%s" % table, [key]) + + + + + + + + russellm + + + + + 13275 + 4dd52d4f3f50 + + + + false + + + + + 2010-08-05 + + + + 62 + + + + transaction.commit_unless_managed(using=db) + + + + + + + + adrian + + + + + 2287 + 3f0790d500a9 + + + + false + + + + + 2006-02-24 + + + + 37 + + + + return default + + + + + + + + russellm + + + + + 13275 + 4dd52d4f3f50 + + + + false + + + + + 2010-08-05 + + + + 64 + + + + value = connections[db].ops.process_clob(row[1]) + + + + + + + + ikelly + + + + + 9862 + 8739c35149dd + + + + false + + + + + 2009-03-13 + + + + 39 + + + + return pickle.loads(base64.decodestring(value)) + + + + + + + + adrian + + + + + 2287 + 3f0790d500a9 + + + + false + + + + + 2006-02-24 + + + + 39 + + + + + + + + + + + + russellm + + + + + 14425 + 793e94ba2037 + + + + false + + + + + 2010-11-19 + + + + 59 + + + + def set(self, key, value, timeout=None, version=None): + + + + + + + + russellm + + + + + 14425 + 793e94ba2037 + + + + false + + + + + 2010-11-19 + + + + 60 + + + + key = self.make_key(key, version=version) + + + + + + + + mtredinnick + + + + + 13568 + 7e0b7bf098d2 + + + + false + + + + + 2010-09-12 + + + + 69 + + + + self.validate_key(key) + + + + + + + + mtredinnick + + + + + 8110 + c787c7f62142 + + + + false + + + + + 2008-08-10 + + + + 41 + + + + self._base_set('set', key, value, timeout) + + + + + + + + mtredinnick + + + + + 6421 + b4175804cc7b + + + + false + + + + + 2007-10-20 + + + + 45 + + + + + + + + + + + + russellm + + + + + 14425 + 793e94ba2037 + + + + false + + + + + 2010-11-19 + + + + 64 + + + + def add(self, key, value, timeout=None, version=None): + + + + + + + + russellm + + + + + 14425 + 793e94ba2037 + + + + false + + + + + 2010-11-19 + + + + 65 + + + + key = self.make_key(key, version=version) + + + + + + + + mtredinnick + + + + + 13568 + 7e0b7bf098d2 + + + + false + + + + + 2010-09-12 + + + + 73 + + + + self.validate_key(key) + + + + + + + + mtredinnick + + + + + 6438 + 5096a56a9ac6 + + + + false + + + + + 2007-10-21 + + + + 44 + + + + return self._base_set('add', key, value, timeout) + + + + + + + + mtredinnick + + + + + 6438 + 5096a56a9ac6 + + + + false + + + + + 2007-10-21 + + + + 45 + + + + + + + + + + + + mtredinnick + + + + + 6421 + b4175804cc7b + + + + false + + + + + 2007-10-20 + + + + 46 + + + + def _base_set(self, mode, key, value, timeout=None): + + + + + + + + adrian + + + + + 2287 + 3f0790d500a9 + + + + false + + + + + 2006-02-24 + + + + 41 + + + + if timeout is None: + + + + + + + + adrian + + + + + 2287 + 3f0790d500a9 + + + + false + + + + + 2006-02-24 + + + + 42 + + + + timeout = self.default_timeout + + + + + + + + russellm + + + + + 13275 + 4dd52d4f3f50 + + + + false + + + + + 2010-08-05 + + + + 76 + + + + db = router.db_for_write(self.cache_model_class) + + + + + + + + russellm + + + + + 13275 + 4dd52d4f3f50 + + + + false + + + + + 2010-08-05 + + + + 77 + + + + table = connections[db].ops.quote_name(self._table) + + + + + + + + russellm + + + + + 13275 + 4dd52d4f3f50 + + + + false + + + + + 2010-08-05 + + + + 78 + + + + cursor = connections[db].cursor() + + + + + + + + russellm + + + + + 13275 + 4dd52d4f3f50 + + + + false + + + + + 2010-08-05 + + + + 79 + + + + + + + + + + + + russellm + + + + + 13275 + 4dd52d4f3f50 + + + + false + + + + + 2010-08-05 + + + + 80 + + + + cursor.execute("SELECT COUNT(*) FROM %s" % table) + + + + + + + + adrian + + + + + 2287 + 3f0790d500a9 + + + + false + + + + + 2006-02-24 + + + + 45 + + + + num = cursor.fetchone()[0] + + + + + + + + adrian + + + + + 2287 + 3f0790d500a9 + + + + false + + + + + 2006-02-24 + + + + 46 + + + + now = datetime.now().replace(microsecond=0) + + + + + + + + adrian + + + + + 2287 + 3f0790d500a9 + + + + false + + + + + 2006-02-24 + + + + 47 + + + + exp = datetime.fromtimestamp(time.time() + timeout).replace(microsecond=0) + + + + + + + + adrian + + + + + 2287 + 3f0790d500a9 + + + + false + + + + + 2006-02-24 + + + + 48 + + + + if num > self._max_entries: + + + + + + + + russellm + + + + + 13275 + 4dd52d4f3f50 + + + + false + + + + + 2010-08-05 + + + + 85 + + + + self._cull(db, cursor, now) + + + + + + + + adrian + + + + + 2287 + 3f0790d500a9 + + + + false + + + + + 2006-02-24 + + + + 50 + + + + encoded = base64.encodestring(pickle.dumps(value, 2)).strip() + + + + + + + + russellm + + + + + 13275 + 4dd52d4f3f50 + + + + false + + + + + 2010-08-05 + + + + 87 + + + + cursor.execute("SELECT cache_key, expires FROM %s WHERE cache_key = %%s" % table, [key]) + + + + + + + + adrian + + + + + 2287 + 3f0790d500a9 + + + + false + + + + + 2006-02-24 + + + + 52 + + + + try: + + + + + + + + mtredinnick + + + + + 9753 + 0ab5ef23e1bc + + + + false + + + + + 2009-03-02 + + + + 59 + + + + result = cursor.fetchone() + + + + + + + + mtredinnick + + + + + 9753 + 0ab5ef23e1bc + + + + false + + + + + 2009-03-02 + + + + 60 + + + + if result and (mode == 'set' or + + + + + + + + mtredinnick + + + + + 9753 + 0ab5ef23e1bc + + + + false + + + + + 2009-03-02 + + + + 61 + + + + (mode == 'add' and result[1] < now)): + + + + + + + + russellm + + + + + 13275 + 4dd52d4f3f50 + + + + false + + + + + 2010-08-05 + + + + 92 + + + + cursor.execute("UPDATE %s SET value = %%s, expires = %%s WHERE cache_key = %%s" % table, + + + + + + + + russellm + + + + + 13275 + 4dd52d4f3f50 + + + + false + + + + + 2010-08-05 + + + + 93 + + + + [encoded, connections[db].ops.value_to_db_datetime(exp), key]) + + + + + + + + adrian + + + + + 2287 + 3f0790d500a9 + + + + false + + + + + 2006-02-24 + + + + 55 + + + + else: + + + + + + + + russellm + + + + + 13275 + 4dd52d4f3f50 + + + + false + + + + + 2010-08-05 + + + + 95 + + + + cursor.execute("INSERT INTO %s (cache_key, value, expires) VALUES (%%s, %%s, %%s)" % table, + + + + + + + + russellm + + + + + 13275 + 4dd52d4f3f50 + + + + false + + + + + 2010-08-05 + + + + 96 + + + + [key, encoded, connections[db].ops.value_to_db_datetime(exp)]) + + + + + + + + adrian + + + + + 2287 + 3f0790d500a9 + + + + false + + + + + 2006-02-24 + + + + 57 + + + + except DatabaseError: + + + + + + + + adrian + + + + + 2287 + 3f0790d500a9 + + + + false + + + + + 2006-02-24 + + + + 58 + + + + # To be threadsafe, updates/inserts are allowed to fail silently + + + + + + + + russellm + + + + + 13275 + 4dd52d4f3f50 + + + + false + + + + + 2010-08-05 + + + + 99 + + + + transaction.rollback_unless_managed(using=db) + + + + + + + + mtredinnick + + + + + 8110 + c787c7f62142 + + + + false + + + + + 2008-08-10 + + + + 65 + + + + return False + + + + + + + + adrian + + + + + 2287 + 3f0790d500a9 + + + + false + + + + + 2006-02-24 + + + + 60 + + + + else: + + + + + + + + russellm + + + + + 13275 + 4dd52d4f3f50 + + + + false + + + + + 2010-08-05 + + + + 102 + + + + transaction.commit_unless_managed(using=db) + + + + + + + + mtredinnick + + + + + 8110 + c787c7f62142 + + + + false + + + + + 2008-08-10 + + + + 68 + + + + return True + + + + + + + + adrian + + + + + 2287 + 3f0790d500a9 + + + + false + + + + + 2006-02-24 + + + + 62 + + + + + + + + + + + + russellm + + + + + 14425 + 793e94ba2037 + + + + false + + + + + 2010-11-19 + + + + 101 + + + + def delete(self, key, version=None): + + + + + + + + russellm + + + + + 14425 + 793e94ba2037 + + + + false + + + + + 2010-11-19 + + + + 102 + + + + key = self.make_key(key, version=version) + + + + + + + + mtredinnick + + + + + 13568 + 7e0b7bf098d2 + + + + false + + + + + 2010-09-12 + + + + 109 + + + + self.validate_key(key) + + + + + + + + russellm + + + + + 14425 + 793e94ba2037 + + + + false + + + + + 2010-11-19 + + + + 104 + + + + + + + + + + + + russellm + + + + + 13275 + 4dd52d4f3f50 + + + + false + + + + + 2010-08-05 + + + + 106 + + + + db = router.db_for_write(self.cache_model_class) + + + + + + + + russellm + + + + + 13275 + 4dd52d4f3f50 + + + + false + + + + + 2010-08-05 + + + + 107 + + + + table = connections[db].ops.quote_name(self._table) + + + + + + + + russellm + + + + + 13275 + 4dd52d4f3f50 + + + + false + + + + + 2010-08-05 + + + + 108 + + + + cursor = connections[db].cursor() + + + + + + + + russellm + + + + + 13275 + 4dd52d4f3f50 + + + + false + + + + + 2010-08-05 + + + + 109 + + + + + + + + + + + + russellm + + + + + 13275 + 4dd52d4f3f50 + + + + false + + + + + 2010-08-05 + + + + 110 + + + + cursor.execute("DELETE FROM %s WHERE cache_key = %%s" % table, [key]) + + + + + + + + russellm + + + + + 13275 + 4dd52d4f3f50 + + + + false + + + + + 2010-08-05 + + + + 111 + + + + transaction.commit_unless_managed(using=db) + + + + + + + + adrian + + + + + 2287 + 3f0790d500a9 + + + + false + + + + + 2006-02-24 + + + + 67 + + + + + + + + + + + + russellm + + + + + 14425 + 793e94ba2037 + + + + false + + + + + 2010-11-19 + + + + 112 + + + + def has_key(self, key, version=None): + + + + + + + + russellm + + + + + 14425 + 793e94ba2037 + + + + false + + + + + 2010-11-19 + + + + 113 + + + + key = self.make_key(key, version=version) + + + + + + + + mtredinnick + + + + + 13568 + 7e0b7bf098d2 + + + + false + + + + + 2010-09-12 + + + + 118 + + + + self.validate_key(key) + + + + + + + + russellm + + + + + 14425 + 793e94ba2037 + + + + false + + + + + 2010-11-19 + + + + 115 + + + + + + + + + + + + russellm + + + + + 13275 + 4dd52d4f3f50 + + + + false + + + + + 2010-08-05 + + + + 114 + + + + db = router.db_for_read(self.cache_model_class) + + + + + + + + russellm + + + + + 13275 + 4dd52d4f3f50 + + + + false + + + + + 2010-08-05 + + + + 115 + + + + table = connections[db].ops.quote_name(self._table) + + + + + + + + russellm + + + + + 13275 + 4dd52d4f3f50 + + + + false + + + + + 2010-08-05 + + + + 116 + + + + cursor = connections[db].cursor() + + + + + + + + russellm + + + + + 13275 + 4dd52d4f3f50 + + + + false + + + + + 2010-08-05 + + + + 117 + + + + + + + + + + + + mtredinnick + + + + + 9753 + 0ab5ef23e1bc + + + + false + + + + + 2009-03-02 + + + + 78 + + + + now = datetime.now().replace(microsecond=0) + + + + + + + + russellm + + + + + 13275 + 4dd52d4f3f50 + + + + false + + + + + 2010-08-05 + + + + 119 + + + + cursor.execute("SELECT cache_key FROM %s WHERE cache_key = %%s and expires > %%s" % table, + + + + + + + + russellm + + + + + 13275 + 4dd52d4f3f50 + + + + false + + + + + 2010-08-05 + + + + 120 + + + + [key, connections[db].ops.value_to_db_datetime(now)]) + + + + + + + + adrian + + + + + 2287 + 3f0790d500a9 + + + + false + + + + + 2006-02-24 + + + + 71 + + + + return cursor.fetchone() is not None + + + + + + + + adrian + + + + + 2287 + 3f0790d500a9 + + + + false + + + + + 2006-02-24 + + + + 72 + + + + + + + + + + + + russellm + + + + + 13275 + 4dd52d4f3f50 + + + + false + + + + + 2010-08-05 + + + + 123 + + + + def _cull(self, db, cursor, now): + + + + + + + + adrian + + + + + 2287 + 3f0790d500a9 + + + + false + + + + + 2006-02-24 + + + + 74 + + + + if self._cull_frequency == 0: + + + + + + + + russellm + + + + + 12116 + c1ad14c551a9 + + + + false + + + + + 2010-01-27 + + + + 87 + + + + self.clear() + + + + + + + + adrian + + + + + 2287 + 3f0790d500a9 + + + + false + + + + + 2006-02-24 + + + + 76 + + + + else: + + + + + + + + russellm + + + + + 13480 + 7351411944a9 + + + + false + + + + + 2010-08-31 + + + + 127 + + + + table = connections[db].ops.quote_name(self._table) + + + + + + + + russellm + + + + + 13275 + 4dd52d4f3f50 + + + + false + + + + + 2010-08-05 + + + + 127 + + + + cursor.execute("DELETE FROM %s WHERE expires < %%s" % table, + + + + + + + + russellm + + + + + 13275 + 4dd52d4f3f50 + + + + false + + + + + 2010-08-05 + + + + 128 + + + + [connections[db].ops.value_to_db_datetime(now)]) + + + + + + + + russellm + + + + + 13275 + 4dd52d4f3f50 + + + + false + + + + + 2010-08-05 + + + + 129 + + + + cursor.execute("SELECT COUNT(*) FROM %s" % table) + + + + + + + + adrian + + + + + 2287 + 3f0790d500a9 + + + + false + + + + + 2006-02-24 + + + + 79 + + + + num = cursor.fetchone()[0] + + + + + + + + adrian + + + + + 2287 + 3f0790d500a9 + + + + false + + + + + 2006-02-24 + + + + 80 + + + + if num > self._max_entries: + + + + + + + + russellm + + + + + 13275 + 4dd52d4f3f50 + + + + false + + + + + 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 + + + + false + + + + + 2010-08-05 + + + + 133 + + + + cursor.execute("DELETE FROM %s WHERE cache_key < %%s" % table, [cursor.fetchone()[0]]) + + + + + + + + russellm + + + + + 12116 + c1ad14c551a9 + + + + false + + + + + 2010-01-27 + + + + 95 + + + + + + + + + + + + russellm + + + + + 12116 + c1ad14c551a9 + + + + false + + + + + 2010-01-27 + + + + 96 + + + + def clear(self): + + + + + + + + russellm + + + + + 13275 + 4dd52d4f3f50 + + + + false + + + + + 2010-08-05 + + + + 136 + + + + db = router.db_for_write(self.cache_model_class) + + + + + + + + russellm + + + + + 13275 + 4dd52d4f3f50 + + + + false + + + + + 2010-08-05 + + + + 137 + + + + table = connections[db].ops.quote_name(self._table) + + + + + + + + russellm + + + + + 13275 + 4dd52d4f3f50 + + + + false + + + + + 2010-08-05 + + + + 138 + + + + cursor = connections[db].cursor() + + + + + + + + russellm + + + + + 13275 + 4dd52d4f3f50 + + + + false + + + + + 2010-08-05 + + + + 139 + + + + cursor.execute('DELETE FROM %s' % table) + + + + + + + + russellm + + + + + 14807 + 905c4a7e1f19 + + + + false + + + + + 2010-12-21 + + + + 143 + + + + + + + + + + + + russellm + + + + + 14807 + 905c4a7e1f19 + + + + false + + + + + 2010-12-21 + + + + 144 + + + + # For backwards compatibility + + + + + + + + russellm + + + + + 14807 + 905c4a7e1f19 + + + + false + + + + + 2010-12-21 + + + + 145 + + + + class CacheClass(DatabaseCache): + + + + + + + + russellm + + + + + 14807 + 905c4a7e1f19 + + + + false + + + + + 2010-12-21 + + + + 146 + + + + pass + + + + \ No newline at end of file diff --git a/plugins/hg4idea/testData/annotate/info.txt b/plugins/hg4idea/testData/annotate/info.txt new file mode 100644 index 000000000000..b459a2df2395 --- /dev/null +++ b/plugins/hg4idea/testData/annotate/info.txt @@ -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) \ No newline at end of file diff --git a/plugins/hg4idea/testData/annotate/outputs/hg_1.7.1 b/plugins/hg4idea/testData/annotate/outputs/hg_1.7.1 new file mode 100644 index 000000000000..3acc13feeb81 --- /dev/null +++ b/plugins/hg4idea/testData/annotate/outputs/hg_1.7.1 @@ -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 diff --git a/plugins/hg4idea/testData/annotate/outputs/hg_1.8.2 b/plugins/hg4idea/testData/annotate/outputs/hg_1.8.2 new file mode 100644 index 000000000000..3acc13feeb81 --- /dev/null +++ b/plugins/hg4idea/testData/annotate/outputs/hg_1.8.2 @@ -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 diff --git a/plugins/hg4idea/testData/annotate/outputs/hg_1.9.0 b/plugins/hg4idea/testData/annotate/outputs/hg_1.9.0 new file mode 100644 index 000000000000..886d778c2800 --- /dev/null +++ b/plugins/hg4idea/testData/annotate/outputs/hg_1.9.0 @@ -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 diff --git a/plugins/hg4idea/testSrc/org/zmlx/hg4idea/test/HgAnnotateCommandTest.java b/plugins/hg4idea/testSrc/org/zmlx/hg4idea/test/HgAnnotateCommandTest.java new file mode 100644 index 000000000000..aee72fd237a6 --- /dev/null +++ b/plugins/hg4idea/testSrc/org/zmlx/hg4idea/test/HgAnnotateCommandTest.java @@ -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 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) 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 annotations = Arrays.asList(annotationNativeOutput.split("(\n|\r|\r\n)")); + List result = (List)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 annotationLines = new ArrayList(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(); + } + } + + +}