/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar

« back to all changes in this revision

Viewing changes to shamap.py

Specify plain string path to Dulwich.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2009 Canonical Ltd
 
1
# Copyright (C) 2009 Jelmer Vernooij <jelmer@samba.org>
2
2
#
3
3
# This program is free software; you can redistribute it and/or modify
4
4
# it under the terms of the GNU General Public License as published by
16
16
 
17
17
"""Map from Git sha's to Bazaar objects."""
18
18
 
 
19
import os
 
20
import threading
 
21
 
19
22
import bzrlib
20
 
 
21
 
from bzrlib.errors import NoSuchRevision
22
 
 
23
 
import os
 
23
from bzrlib.errors import (
 
24
    NoSuchRevision,
 
25
    )
24
26
 
25
27
 
26
28
def check_pysqlite_version(sqlite3):
46
48
    raise bzrlib.errors.BzrError("missing sqlite library")
47
49
 
48
50
 
 
51
_mapdbs = threading.local()
 
52
def mapdbs():
 
53
    """Get a cache for this thread's db connections."""
 
54
    try:
 
55
        return _mapdbs.cache
 
56
    except AttributeError:
 
57
        _mapdbs.cache = {}
 
58
        return _mapdbs.cache
 
59
 
 
60
 
49
61
class GitShaMap(object):
50
 
 
51
 
    def __init__(self, transport):
52
 
        self.transport = transport
53
 
        self.db = sqlite3.connect(
54
 
            os.path.join(self.transport.local_abspath("."), "git.db"))
 
62
    """Git<->Bzr revision id mapping database."""
 
63
 
 
64
    def add_entry(self, sha, type, type_data):
 
65
        """Add a new entry to the database.
 
66
        """
 
67
        raise NotImplementedError(self.add_entry)
 
68
 
 
69
    def add_entries(self, entries):
 
70
        """Add multiple new entries to the database.
 
71
        """
 
72
        for e in entries:
 
73
            self.add_entry(*e)
 
74
 
 
75
    def lookup_tree(self, fileid, revid):
 
76
        """Lookup the SHA of a git tree."""
 
77
        raise NotImplementedError(self.lookup_tree)
 
78
 
 
79
    def lookup_blob(self, fileid, revid):
 
80
        raise NotImplementedError(self.lookup_blob)
 
81
 
 
82
    def lookup_git_sha(self, sha):
 
83
        """Lookup a Git sha in the database.
 
84
 
 
85
        :param sha: Git object sha
 
86
        :return: (type, type_data) with type_data:
 
87
            revision: revid, tree sha
 
88
        """
 
89
        raise NotImplementedError(self.lookup_git_sha)
 
90
 
 
91
    def revids(self):
 
92
        """List the revision ids known."""
 
93
        raise NotImplementedError(self.revids)
 
94
 
 
95
    def commit(self):
 
96
        """Commit any pending changes."""
 
97
 
 
98
 
 
99
class DictGitShaMap(GitShaMap):
 
100
 
 
101
    def __init__(self):
 
102
        self.dict = {}
 
103
 
 
104
    def add_entry(self, sha, type, type_data):
 
105
        self.dict[sha] = (type, type_data)
 
106
 
 
107
    def lookup_git_sha(self, sha):
 
108
        return self.dict[sha]
 
109
 
 
110
    def lookup_tree(self, fileid, revid):
 
111
        for k, v in self.dict.iteritems():
 
112
            if v == ("tree", (fileid, revid)):
 
113
                return k
 
114
        raise KeyError((fileid, revid))
 
115
 
 
116
    def lookup_blob(self, fileid, revid):
 
117
        for k, v in self.dict.iteritems():
 
118
            if v == ("blob", (fileid, revid)):
 
119
                return k
 
120
        raise KeyError((fileid, revid))
 
121
 
 
122
    def revids(self):
 
123
        for key, (type, type_data) in self.dict.iteritems():
 
124
            if type == "commit":
 
125
                yield type_data[0]
 
126
 
 
127
 
 
128
class SqliteGitShaMap(GitShaMap):
 
129
 
 
130
    def __init__(self, path=None):
 
131
        self.path = path
 
132
        if path is None:
 
133
            self.db = sqlite3.connect(":memory:")
 
134
        else:
 
135
            if not mapdbs().has_key(path):
 
136
                mapdbs()[path] = sqlite3.connect(path)
 
137
            self.db = mapdbs()[path]    
55
138
        self.db.executescript("""
56
139
        create table if not exists commits(sha1 text, revid text, tree_sha text);
57
140
        create index if not exists commit_sha1 on commits(sha1);
 
141
        create unique index if not exists commit_revid on commits(revid);
58
142
        create table if not exists blobs(sha1 text, fileid text, revid text);
59
143
        create index if not exists blobs_sha1 on blobs(sha1);
 
144
        create unique index if not exists blobs_fileid_revid on blobs(fileid, revid);
60
145
        create table if not exists trees(sha1 text, fileid text, revid text);
61
146
        create index if not exists trees_sha1 on trees(sha1);
 
147
        create unique index if not exists trees_fileid_revid on trees(fileid, revid);
62
148
""")
63
149
 
 
150
    @classmethod
 
151
    def from_repository(cls, repository):
 
152
        return cls(os.path.join(repository._transport.local_abspath("."), "git.db"))
 
153
 
64
154
    def _parent_lookup(self, revid):
65
 
        return self.db.execute("select sha1 from commits where revid = ?", (revid,)).fetchone()[0].encode("utf-8")
 
155
        row = self.db.execute("select sha1 from commits where revid = ?", (revid,)).fetchone()
 
156
        if row is not None:
 
157
            return row[0].encode("utf-8")
 
158
        raise KeyError
 
159
 
 
160
    def commit(self):
 
161
        self.db.commit()
66
162
 
67
163
    def add_entry(self, sha, type, type_data):
68
164
        """Add a new entry to the database.
71
167
        assert isinstance(sha, str), "type was %r" % sha
72
168
        if type == "commit":
73
169
            self.db.execute("replace into commits (sha1, revid, tree_sha) values (?, ?, ?)", (sha, type_data[0], type_data[1]))
74
 
        elif type == "blob":
75
 
            self.db.execute("replace into blobs (sha1, fileid, revid) values (?, ?, ?)", (sha, type_data[0], type_data[1]))
76
 
        elif type == "tree":
77
 
            self.db.execute("replace into trees (sha1, fileid, revid) values (?, ?, ?)", (sha, type_data[0], type_data[1]))
 
170
        elif type in ("blob", "tree"):
 
171
            self.db.execute("replace into %ss (sha1, fileid, revid) values (?, ?, ?)" % type, (sha, type_data[0], type_data[1]))
78
172
        else:
79
173
            raise AssertionError("Unknown type %s" % type)
80
174
 
 
175
    def lookup_tree(self, fileid, revid):
 
176
        row = self.db.execute("select sha1 from trees where fileid = ? and revid = ?", (fileid,revid)).fetchone()
 
177
        if row is None:
 
178
            raise KeyError((fileid, revid))
 
179
        return row[0].encode("utf-8")
 
180
 
 
181
    def lookup_blob(self, fileid, revid):
 
182
        row = self.db.execute("select sha1 from blobs where fileid = ? and revid = ?", (fileid, revid)).fetchone()
 
183
        if row is None:
 
184
            raise KeyError((fileid, revid))
 
185
        return row[0].encode("utf-8")
 
186
 
81
187
    def lookup_git_sha(self, sha):
82
188
        """Lookup a Git sha in the database.
83
189
 
85
191
        :return: (type, type_data) with type_data:
86
192
            revision: revid, tree sha
87
193
        """
 
194
        def format(type, row):
 
195
            return (type, (row[0].encode("utf-8"), row[1].encode("utf-8")))
88
196
        row = self.db.execute("select revid, tree_sha from commits where sha1 = ?", (sha,)).fetchone()
89
197
        if row is not None:
90
 
            return ("commit", row)
 
198
            return format("commit", row)
91
199
        row = self.db.execute("select fileid, revid from blobs where sha1 = ?", (sha,)).fetchone()
92
200
        if row is not None:
93
 
            return ("blob", row)
 
201
            return format("blob", row)
94
202
        row = self.db.execute("select fileid, revid from trees where sha1 = ?", (sha,)).fetchone()
95
203
        if row is not None:
96
 
            return ("tree", row)
 
204
            return format("tree", row)
97
205
        raise KeyError(sha)
98
206
 
99
207
    def revids(self):
 
208
        """List the revision ids known."""
100
209
        for row in self.db.execute("select revid from commits").fetchall():
101
 
            yield row[0]
 
210
            yield row[0].encode("utf-8")