Introduce proper XHTML boilerplate into the cvs2svn webpages.
[cvs2svn.git] / cvs2svn_lib / symbolings_reader.py
blobfec4d0d494c3b3929d25b7359d8e01409880a3c4
1 # (Be in -*- python -*- mode.)
3 # ====================================================================
4 # Copyright (c) 2000-2006 CollabNet. All rights reserved.
6 # This software is licensed as described in the file COPYING, which
7 # you should have received as part of this distribution. The terms
8 # are also available at http://subversion.tigris.org/license-1.html.
9 # If newer versions of this license are posted there, you may use a
10 # newer version instead, at your option.
12 # This software consists of voluntary contributions made by many
13 # individuals. For exact contribution history, see the revision
14 # history and logs, available at http://cvs2svn.tigris.org/.
15 # ====================================================================
17 """This module contains database facilities used by cvs2svn."""
20 from __future__ import generators
22 from boolean import *
23 import config
24 from context import Ctx
25 from artifact_manager import artifact_manager
26 import database
27 from openings_closings import OpeningsClosingsMap
28 from symbolic_name_filling_guide import SymbolicNameFillingGuide
31 class SymbolingsReader:
32 """Provides an interface to the SYMBOL_OPENINGS_CLOSINGS_SORTED file
33 and the SYMBOL_OFFSETS_DB. Does the heavy lifting of finding and
34 returning the correct opening and closing Subversion revision
35 numbers for a given symbolic name."""
37 def __init__(self):
38 """Opens the SYMBOL_OPENINGS_CLOSINGS_SORTED for reading, and
39 reads the offsets database into memory."""
41 self.symbolings = open(
42 artifact_manager.get_temp_file(
43 config.SYMBOL_OPENINGS_CLOSINGS_SORTED),
44 'r')
45 # The offsets_db is really small, and we need to read and write
46 # from it a fair bit, so suck it into memory
47 offsets_db = database.Database(
48 artifact_manager.get_temp_file(config.SYMBOL_OFFSETS_DB),
49 database.DB_OPEN_READ)
50 self.offsets = { }
51 for key in offsets_db:
52 #print " ZOO:", key, offsets_db[key]
53 self.offsets[key] = offsets_db[key]
55 def filling_guide_for_symbol(self, symbolic_name, svn_revnum):
56 """Given SYMBOLIC_NAME and SVN_REVNUM, return a new
57 SymbolicNameFillingGuide object.
59 Note that if we encounter an opening rev in this fill, but the
60 corresponding closing rev takes place later than SVN_REVNUM, the
61 closing will not be passed to SymbolicNameFillingGuide in this
62 fill (and will be discarded when encountered in a later fill).
63 This is perfectly fine, because we can still do a valid fill
64 without the closing--we always try to fill what we can as soon as
65 we can."""
67 openings_closings_map = OpeningsClosingsMap(symbolic_name)
69 # It's possible to have a branch start with a file that was added
70 # on a branch
71 if self.offsets.has_key(symbolic_name):
72 # set our read offset for self.symbolings to the offset for
73 # symbolic_name
74 self.symbolings.seek(self.offsets[symbolic_name])
76 while 1:
77 fpos = self.symbolings.tell()
78 line = self.symbolings.readline().rstrip()
79 if not line:
80 break
81 name, revnum, type, branch_name, cvs_path = line.split(" ", 4)
82 if branch_name == '*':
83 svn_path = Ctx().project.make_trunk_path(cvs_path)
84 else:
85 svn_path = Ctx().project.make_branch_path(branch_name, cvs_path)
86 revnum = int(revnum)
87 if revnum > svn_revnum or name != symbolic_name:
88 break
89 openings_closings_map.register(svn_path, revnum, type)
91 # get current offset of the read marker and set it to the offset
92 # for the beginning of the line we just read if we used anything
93 # we read.
94 if not openings_closings_map.is_empty():
95 self.offsets[symbolic_name] = fpos
97 return SymbolicNameFillingGuide(openings_closings_map)