]>
code.delx.au - offlineimap/blob - offlineimap/folder/LocalStatus.py
1 # Local status cache virtual folder
2 # Copyright (C) 2002 - 2008 John Goerzen
3 # <jgoerzen@complete.org>
5 # This program is free software; you can redistribute it and/or modify
6 # it under the terms of the GNU General Public License as published by
7 # the Free Software Foundation; either version 2 of the License, or
8 # (at your option) any later version.
10 # This program is distributed in the hope that it will be useful,
11 # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 # GNU General Public License for more details.
15 # You should have received a copy of the GNU General Public License
16 # along with this program; if not, write to the Free Software
17 # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
19 from Base
import BaseFolder
22 from pysqlite2
import dbapi2
as sqlite
24 magicline
= "OFFLINEIMAP LocalStatus CACHE DATA - DO NOT MODIFY - FORMAT 1"
25 newmagicline
= "OFFLINEIMAP LocalStatus NOW IN SQLITE, DO NOT MODIFY"
27 class LocalStatusFolder(BaseFolder
):
31 self
.connection
.close()
33 def __init__(self
, root
, name
, repository
, accountname
):
37 self
.filename
= os
.path
.join(root
, name
)
38 self
.filename
= repository
.getfolderfilename(name
)
40 self
.repository
= repository
41 self
.savelock
= threading
.Lock()
43 self
.accountname
= accountname
44 self
.count
= 0 # used for batching operations before commit
45 BaseFolder
.__init
__(self
)
46 self
.dbfilename
= self
.filename
+ '.sqlite'
49 if os
.path
.exists(self
.filename
):
50 self
.connection
= sqlite
.connect(self
.dbfilename
)
51 self
.cursor
= self
.connection
.cursor()
52 self
.cursor
.execute('CREATE TABLE status (id INTEGER PRIMARY KEY, flags VARCHAR(50))')
53 if self
.isnewfolder():
56 file = open(self
.filename
, "rt")
58 line
= file.readline().strip()
59 assert(line
== magicline
)
60 for line
in file.xreadlines():
62 uid
, flags
= line
.split(':')
64 flags
= [x
for x
in flags
]
66 flags
= ''.join(flags
)
67 self
.cursor
.execute('INSERT INTO status (id,flags) VALUES (?,?)',
70 self
.connection
.commit()
71 os
.rename(self
.filename
, self
.filename
+ ".old")
73 self
.connection
.close()
76 if not os
.path
.exists(self
.dbfilename
):
77 self
.connection
= sqlite
.connect(self
.dbfilename
)
78 self
.cursor
= self
.connection
.cursor()
79 self
.cursor
.execute('CREATE TABLE status (id INTEGER PRIMARY KEY, flags VARCHAR(50))')
81 self
.connection
= sqlite
.connect(self
.dbfilename
)
82 self
.cursor
= self
.connection
.cursor()
86 def getaccountname(self
):
87 return self
.accountname
89 def storesmessages(self
):
92 def isnewfolder(self
):
93 return not os
.path
.exists(self
.dbfilename
)
104 def getfullname(self
):
107 def deletemessagelist(self
):
108 if not self
.isnewfolder():
110 self
.connection
.close()
111 os
.unlink(self
.dbfilename
)
113 def cachemessagelist(self
):
121 self
.connection
.commit()
123 def getmessagelist(self
):
124 if self
.isnewfolder():
125 self
.messagelist
= {}
128 self
.messagelist
= {}
129 self
.cursor
.execute('SELECT id,flags from status')
130 for row
in self
.cursor
:
131 flags
= [x
for x
in row
[1]]
132 self
.messagelist
[row
[0]] = {'uid': row
[0], 'flags': flags
}
134 return self
.messagelist
136 def uidexists(self
,uid
):
137 self
.cursor
.execute('SELECT id FROM status WHERE id=:id',{'id': uid
})
138 for row
in self
.cursor
:
143 def getmessageuidlist(self
):
144 self
.cursor
.execute('SELECT id from status')
146 for row
in self
.cursor
:
150 def getmessagecount(self
):
151 self
.cursor
.execute('SELECT count(id) from status');
152 row
= self
.cursor
.fetchone()
155 def savemessage(self
, uid
, content
, flags
, rtime
):
157 # We cannot assign a uid.
160 if self
.uidexists(uid
): # already have it
161 self
.savemessageflags(uid
, flags
)
164 self
.messagelist
[uid
] = {'uid': uid
, 'flags': flags
, 'time': rtime
}
166 flags
= ''.join(flags
)
167 self
.cursor
.execute('INSERT INTO status (id,flags) VALUES (?,?)',
172 def getmessageflags(self
, uid
):
173 self
.cursor
.execute('SELECT flags FROM status WHERE id=:id',
175 for row
in self
.cursor
:
176 flags
= [x
for x
in row
[0]]
180 def getmessagetime(self
, uid
):
181 return self
.messagelist
[uid
]['time']
183 def savemessageflags(self
, uid
, flags
):
184 self
.messagelist
[uid
] = {'uid': uid
, 'flags': flags
}
186 flags
= ''.join(flags
)
187 self
.cursor
.execute('UPDATE status SET flags=? WHERE id=?',(flags
,uid
))
188 self
.count
= self
.count
+ 1
189 if self
.count
== 100:
193 def deletemessage(self
, uid
):
194 if not self
.uidexists(uid
):
197 if uid
in self
.messagelist
:
198 del(self
.messagelist
[uid
])
200 self
.cursor
.execute('DELETE FROM status WHERE id=:id', {'id': uid
})