source: tracdarcs/tracdarcs/repository.py @ 28

Revision 28, 8.3 KB checked in by sreeram@…, 7 years ago (diff)

fixed typo bug in updatedb.py, treat CHANGE_MOVED_EDITED as just moved instead of just edited in repository.py

Line 
1import os, StringIO, mimetypes
2from trac.versioncontrol import Repository, Node, Changeset, \
3        NoSuchChangeset, NoSuchNode
4
5from command import DarcsCommand
6from updatedb import update_darcsdb
7from dbutil import NODE_FILE_TYPE, NODE_DIR_TYPE
8from dbutil import CHANGE_ADDED, CHANGE_REMOVED, CHANGE_MOVED, \
9        CHANGE_EDITED, CHANGE_MOVED_EDITED
10from dbutil import query_nodes_for_revision
11import ann2ascii
12
13_node_type_map = {
14        NODE_FILE_TYPE : Node.FILE,
15        NODE_DIR_TYPE : Node.DIRECTORY
16        }
17
18_change_map = {
19        CHANGE_ADDED : Changeset.ADD,
20        CHANGE_REMOVED : Changeset.DELETE,
21        CHANGE_MOVED : Changeset.MOVE,
22        CHANGE_EDITED : Changeset.EDIT,
23        #FIXME: treat moved&edited as just moved?
24        CHANGE_MOVED_EDITED : Changeset.MOVE
25        }
26
27def get_node_type( db, node_id ) :
28    c = db.cursor()
29    c.execute( 'SELECT node_type FROM darcs_nodes ' +
30            'WHERE node_id = %s', (node_id,) )
31    return c.fetchone()[0]
32
33def get_prev_path_rev( db, node_id, rev ) :
34    c = db.cursor()
35    c.execute( 'SELECT path,rev FROM darcs_node_changes ' +
36            'WHERE node_id = %s AND rev < %s ' +
37            'ORDER BY rev DESC LIMIT 1', (node_id,rev) )
38    path,rev = c.fetchone()
39    return path,rev
40
41class DarcsRepository( Repository ) :
42    def __init__( self, db, path, log, config ) :
43        Repository.__init__( self, path, None, log )
44        self.db = db
45        self.path = path
46        self.log = log
47        self.config = config
48        self.__cmd = DarcsCommand( 'darcs', path, log )
49        update_darcsdb( db, self.__cmd )
50
51    def close( self ) :
52        pass
53
54    def get_changeset( self, rev ) :
55        rev = self.normalize_rev( rev )
56        return DarcsChangeset( self.db, rev )
57
58    def get_node( self, path, rev=None ) :
59        path = self.normalize_path( path )
60        rev = self.normalize_rev( rev )
61        if path == '/' :
62            node_id = None
63            node_type = NODE_DIR_TYPE
64            last_rev = rev
65        else :
66            c = self.db.cursor()
67            q = query_nodes_for_revision( rev )
68            q += ' AND dnc.path = %s'
69            c.execute( q, (path,) )
70            row = c.fetchone()
71            if row is None :
72                raise NoSuchNode( path, rev )
73            node_id,last_rev = row[:2]
74            node_type = get_node_type( self.db, node_id )
75        return DarcsNode( node_id, node_type, path, last_rev,
76                self.db, self.__cmd )
77
78    def get_oldest_rev( self ) :
79        if self.get_youngest_rev() is None :
80            return None
81        return 1
82
83    def get_youngest_rev( self ) :
84        c = self.db.cursor()
85        c.execute( 'SELECT rev FROM darcs_revisions ' +
86                'ORDER BY rev DESC LIMIT 1' )
87        row = c.fetchone()
88        return row and row[0] or None
89
90    def previous_rev( self, rev ) :
91        rev = self.normalize_rev( rev )
92        if rev > 1 :
93            return rev-1
94        return None
95
96    def next_rev( self, rev, path='' ) :
97        rev = self.normalize_rev( rev )
98        if rev < self.get_youngest_rev() :
99            return rev+1
100        return None
101
102    def rev_older_than( self, rev1, rev2 ) :
103        return self.normalize_rev(rev1) < self.normalize_rev(rev2)
104
105    def get_path_history( self, path, rev=None, limit=None ) :
106        # this is not correct
107        #return self.get_node( path, rev ).get_history( limit )
108
109        #TODO: implement
110        assert False
111
112    def normalize_path( self, path ) :
113        return path and path.strip('/') or '/'
114
115    def normalize_rev( self, rev ) :
116        youngest = self.get_youngest_rev()
117        if rev is None :
118            return youngest
119        rev = int( rev )
120        if rev > youngest :
121            rev = youngest
122        return rev
123
124    def get_changes( self, old_path, old_rev, new_path, new_rev,
125            ignore_ancestry=1 ) :
126        #TODO: implement
127        assert False
128
129class DarcsNode( Node ) :
130    def __init__( self, node_id, node_type, path, rev,
131            db, cmd ) :
132        kind = _node_type_map[node_type]
133        Node.__init__( self, path, rev, kind )
134        self.__node_id = node_id
135        self.__node_type = node_type
136        self.__db = db
137        self.__cmd = cmd
138        self._init_created()
139
140    def _init_created( self ) :
141        if self.__node_id is None :
142            return
143        c = self.__db.cursor()
144        c.execute( 'SELECT rev,path FROM darcs_node_changes ' +
145                'WHERE node_id = %s ORDER BY rev LIMIT 1',
146                (self.__node_id,) )
147        self.created_rev, self.created_path = c.fetchone()
148
149    def get_content( self ) :
150        if self.__node_type == NODE_DIR_TYPE :
151            return None
152        c = self.__db.cursor()
153        c.execute( 'SELECT hash FROM darcs_revisions ' +
154                'WHERE rev = %s', (self.rev,) )
155        hash = c.fetchone()[0]
156        annotate = self.__cmd.annotate( hash, self.path )
157        ann = ann2ascii.parse_annotate( StringIO.StringIO(annotate) )
158        out = StringIO.StringIO()
159        ann.write( out )
160        return StringIO.StringIO( out.getvalue() )
161
162    def get_entries( self ) :
163        if self.__node_type == NODE_FILE_TYPE :
164            return
165        q = query_nodes_for_revision( self.rev )
166        if self.__node_id is None :
167            q += ' AND dnc.parent_id IS NULL'
168        else :
169            q += ' AND dnc.parent_id = %d' % self.__node_id
170        c = self.__db.cursor()
171        c.execute( q )
172        for node_id,rev,path,_ in c :
173            node_type = get_node_type( self.__db, node_id )
174            yield DarcsNode( node_id, node_type, path, rev,
175                    self.__db, self.__cmd )
176
177    def get_history( self, limit=None ) :
178        if self.path == '/' :
179            yield (self.path,1,Changeset.ADD)
180            return
181        c = self.__db.cursor()
182        q = 'SELECT path,rev,change FROM darcs_node_changes ' + \
183                'WHERE node_id = %s AND rev <= %s ' + \
184                'ORDER BY rev DESC'
185        if limit is not None :
186            q += ' LIMIT %d' % limit
187        c.execute( q, (self.__node_id,self.rev) )
188        for path,rev,change in c :
189            yield ( path, rev, _change_map[change] )
190
191    def get_properties( self ) :
192        return {}
193
194    def get_content_length( self ) :
195        if self.isdir :
196            return None
197        return len(self.get_content().read())
198
199    def get_content_type( self ) :
200        if self.isdir :
201            return None
202        return mimetypes.guess_type( self.path )[0]
203
204    def get_name( self ) :
205        return os.path.split( self.path )[1]
206
207    def get_last_modified( self ) :
208        if self.__node_id is None :
209            return 0
210        c = self.__db.cursor()
211        c.execute( 'SELECT rev FROM darcs_node_changes ' +
212                'WHERE node_id = %s AND rev <= %s ' +
213                'ORDER BY rev DESC LIMIT 1',
214                (self.__node_id,self.rev) )
215        rev = c.fetchone()[0]
216        c.execute( 'SELECT time FROM darcs_revisions ' +
217                'WHERE rev = %s', (rev,) )
218        return c.fetchone()[0]
219
220class DarcsChangeset( Changeset ) :
221    def __init__( self, db, rev ) :
222        c = db.cursor()
223        c.execute( 'SELECT author,time,name,comment ' +
224                'FROM darcs_revisions WHERE rev = %s', (rev,) )
225        row = c.fetchone()
226        if row is None :
227            raise NoSuchChangeset( rev )
228        author,date,name,comment = row
229        msg = name
230        if comment :
231            msg += '\n' + comment
232        Changeset.__init__( self, rev, msg, author, date )
233        self.__db = db
234
235    def get_changes( self ) :
236        c = self.__db.cursor()
237        c.execute( 'SELECT node_id,path,change FROM darcs_node_changes ' +
238                'WHERE rev = %s', (self.rev,) )
239        for node_id,path,change in c :
240            node_type = get_node_type( self.__db, node_id )
241            kind = _node_type_map[node_type]
242            if change == CHANGE_ADDED :
243                prev_path = prev_rev = None
244            else :
245                prev_path,prev_rev = get_prev_path_rev( self.__db,
246                        node_id, self.rev )
247            change = _change_map[change]
248            yield (path,kind,change,prev_path,prev_rev)
249
250    def get_properties( self ) :
251        return []
Note: See TracBrowser for help on using the repository browser.