/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

Use public properties to set git objects values.

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()
 
162
 
 
163
    def add_entries(self, entries):
 
164
        trees = []
 
165
        blobs = []
 
166
        for sha, type, type_data in entries:
 
167
            assert isinstance(type_data[0], str)
 
168
            assert isinstance(type_data[1], str)
 
169
            entry = (sha.decode("utf-8"), type_data[0].decode("utf-8"), 
 
170
                     type_data[1].decode("utf-8"))
 
171
            if type == "tree":
 
172
                trees.append(entry)
 
173
            elif type == "blob":
 
174
                blobs.append(entry)
 
175
            else:
 
176
                raise AssertionError
 
177
        if trees:
 
178
            self.db.executemany("replace into trees (sha1, fileid, revid) values (?, ?, ?)", trees)
 
179
        if blobs:
 
180
            self.db.executemany("replace into blobs (sha1, fileid, revid) values (?, ?, ?)", blobs)
 
181
 
66
182
 
67
183
    def add_entry(self, sha, type, type_data):
68
184
        """Add a new entry to the database.
71
187
        assert isinstance(sha, str), "type was %r" % sha
72
188
        if type == "commit":
73
189
            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]))
 
190
        elif type in ("blob", "tree"):
 
191
            self.db.execute("replace into %ss (sha1, fileid, revid) values (?, ?, ?)" % type, (sha, type_data[0], type_data[1]))
78
192
        else:
79
193
            raise AssertionError("Unknown type %s" % type)
80
194
 
 
195
    def lookup_tree(self, fileid, revid):
 
196
        row = self.db.execute("select sha1 from trees where fileid = ? and revid = ?", (fileid,revid)).fetchone()
 
197
        if row is None:
 
198
            raise KeyError((fileid, revid))
 
199
        return row[0].encode("utf-8")
 
200
 
 
201
    def lookup_blob(self, fileid, revid):
 
202
        row = self.db.execute("select sha1 from blobs where fileid = ? and revid = ?", (fileid, revid)).fetchone()
 
203
        if row is None:
 
204
            raise KeyError((fileid, revid))
 
205
        return row[0].encode("utf-8")
 
206
 
81
207
    def lookup_git_sha(self, sha):
82
208
        """Lookup a Git sha in the database.
83
209
 
85
211
        :return: (type, type_data) with type_data:
86
212
            revision: revid, tree sha
87
213
        """
 
214
        def format(type, row):
 
215
            return (type, (row[0].encode("utf-8"), row[1].encode("utf-8")))
88
216
        row = self.db.execute("select revid, tree_sha from commits where sha1 = ?", (sha,)).fetchone()
89
217
        if row is not None:
90
 
            return ("commit", row)
 
218
            return format("commit", row)
91
219
        row = self.db.execute("select fileid, revid from blobs where sha1 = ?", (sha,)).fetchone()
92
220
        if row is not None:
93
 
            return ("blob", row)
 
221
            return format("blob", row)
94
222
        row = self.db.execute("select fileid, revid from trees where sha1 = ?", (sha,)).fetchone()
95
223
        if row is not None:
96
 
            return ("tree", row)
 
224
            return format("tree", row)
97
225
        raise KeyError(sha)
98
226
 
99
227
    def revids(self):
 
228
        """List the revision ids known."""
100
229
        for row in self.db.execute("select revid from commits").fetchall():
101
 
            yield row[0]
 
230
            yield row[0].encode("utf-8")