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."""
21 from cvs2svn_lib
.boolean
import *
22 from cvs2svn_lib
import config
23 from cvs2svn_lib
.context
import Ctx
24 from cvs2svn_lib
.artifact_manager
import artifact_manager
25 from cvs2svn_lib
.database
import Database
26 from cvs2svn_lib
.database
import DB_OPEN_READ
27 from cvs2svn_lib
.openings_closings
import OpeningsClosingsMap
28 from cvs2svn_lib
.symbol_filling_guide
import SymbolFillingGuide
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."""
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
),
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
48 artifact_manager
.get_temp_file(config
.SYMBOL_OFFSETS_DB
), 'rb')
49 # A map from symbol_id to offset.
50 self
.offsets
= cPickle
.load(offsets_db
)
53 def filling_guide_for_symbol(self
, symbol
, svn_revnum
):
54 """Given SYMBOL and SVN_REVNUM, return a new SymbolFillingGuide object.
56 SYMBOL is a Symbol instance. Note that if we encounter an opening
57 rev in this fill, but the corresponding closing rev takes place
58 later than SVN_REVNUM, the closing will not be passed to
59 SymbolFillingGuide in this fill (and will be discarded when
60 encountered in a later fill). This is perfectly fine, because we
61 can still do a valid fill without the closing--we always try to
62 fill what we can as soon as we can."""
64 openings_closings_map
= OpeningsClosingsMap(symbol
)
66 # It's possible to have a branch start with a file that was added
68 if symbol
.id in self
.offsets
:
69 # Set our read offset for self.symbolings to the offset for this
71 self
.symbolings
.seek(self
.offsets
[symbol
.id])
74 fpos
= self
.symbolings
.tell()
75 line
= self
.symbolings
.readline().rstrip()
78 id, revnum
, type, branch_id
, cvs_file_id
= line
.split()
80 cvs_file_id
= int(cvs_file_id
, 16)
81 cvs_file
= Ctx()._cvs
_file
_db
.get_file(cvs_file_id
)
83 svn_path
= Ctx().project
.make_trunk_path(cvs_file
.cvs_path
)
85 branch_id
= int(branch_id
, 16)
86 svn_path
= Ctx().project
.make_branch_path(
87 Ctx()._symbol
_db
.get_name(branch_id
), cvs_file
.cvs_path
)
89 if revnum
> svn_revnum
or id != symbol
.id:
91 openings_closings_map
.register(svn_path
, revnum
, type)
93 # get current offset of the read marker and set it to the offset
94 # for the beginning of the line we just read if we used anything
96 if not openings_closings_map
.is_empty():
97 self
.offsets
[symbol
.id] = fpos
99 return SymbolFillingGuide(openings_closings_map
)