public class SqliteMailbox extends Mailbox.Default implements MailTree {
- public MailTree slash(String name, boolean create) { return null; }
+ public MailTree slash(String name, boolean create) {
+ String p = file.getAbsolutePath();
+ if (p.endsWith(".sqlite")) p = p.substring(0, p.length()-".sqlite".length());
+ return FileBasedMailbox.getFileBasedMailbox(p+"/"+name, create);
+ }
public String[] children() { return new String[0]; }
public void rmdir(String subdir) { throw new RuntimeException("invalid"); }
public void rename(String subdir, MailTree newParent, String newName) { throw new RuntimeException("invalid"); }
* allowed and any attempt to insert a new row will fail with an
* SQLITE_FULL error.
*/
- // FIXME: should messageid_ be decared unique?
private static final String columns_ =
- "uid_ INTEGER PRIMARY KEY AUTOINCREMENT, messageid_ unique,from_,to_,date_,subject_,headers_,body_,flags_";
+ "uid_ INTEGER PRIMARY KEY AUTOINCREMENT, messageid_,from_,to_,date_,subject_,headers_,body_,flags_";
private final int uidValidity;
private final File file;
+ private final SqliteDB db;
+
public int uidValidity() { return uidValidity; }
public String toString() { return file.getName(); }
public SqliteMailbox(String filename) throws SQLException {
+ ResultSet rs = null;
try {
this.file = new File(filename);
+ this.db = new SqliteDB(filename);
+ this.db.setFastButDangerous(false); // actually changes from FULL to ON
+ /*
Class.forName("org.sqlite.JDBC");
conn = DriverManager.getConnection("jdbc:sqlite:"+filename);
+ */
+ conn = db.getConnection();
conn.prepareStatement("create table if not exists uidvalidity (uidvalidity)").executeUpdate();
- ResultSet rs = conn.prepareStatement("select uidvalidity from uidvalidity").executeQuery();
- if (!rs.next()) {
- this.uidValidity = new Random().nextInt();
- PreparedStatement ps = conn.prepareStatement("insert into uidvalidity (uidvalidity) values (?)");
- ps.setInt(1, uidValidity);
- ps.executeUpdate();
- } else {
- this.uidValidity = rs.getInt(1);
- }
- conn.prepareStatement("create table if not exists 'mail' ("+columns_+")").executeUpdate();
- for(String name : indexedColumns)
- conn.prepareStatement("create index if not exists "+name+"index on mail("+name+");").executeUpdate();
+ try {
+ rs = conn.prepareStatement("select uidvalidity from uidvalidity").executeQuery();
+ if (!rs.next()) {
+ this.uidValidity = new Random().nextInt();
+ PreparedStatement ps = conn.prepareStatement("insert into uidvalidity (uidvalidity) values (?)");
+ ps.setInt(1, uidValidity);
+ ps.executeUpdate();
+ } else {
+ this.uidValidity = rs.getInt(1);
+ }
+ conn.prepareStatement("create table if not exists 'mail' ("+columns_+")").executeUpdate();
+ for(String name : indexedColumns)
+ conn.prepareStatement("create index if not exists "+name+"index on mail("+name+");").executeUpdate();
+ } finally { db.close(rs); }
}
catch (SQLException e) { throw new RuntimeException(e); }
- catch (ClassNotFoundException e) { throw new RuntimeException(e); }
+ //catch (ClassNotFoundException e) { throw new RuntimeException(e); }
}
private HashMap<Integer,Integer> imapToUid = new HashMap<Integer,Integer>();
uidToImap.clear();
PreparedStatement q = conn.prepareStatement("select uid_ from mail");
ResultSet rs = q.executeQuery();
- int num = 1;
- while(rs.next()) {
- imapToUid.put(num, rs.getInt(1));
- uidToImap.put(rs.getInt(1), num);
- num++;
- }
- imapNumberCacheValid = true;
+ try {
+ int num = 1;
+ while(rs.next()) {
+ imapToUid.put(num, rs.getInt(1));
+ uidToImap.put(rs.getInt(1), num);
+ num++;
+ }
+ imapNumberCacheValid = true;
+ } finally { db.close(rs); }
}
}
public int queryImapNumberCache(int uid) throws SQLException {
PreparedStatement q = conn.prepareStatement("select max(uid_) from mail");
ResultSet rs = q.executeQuery();
//if (!rs.next()) return -1;
- if (!rs.next()) throw new RuntimeException("select max(uid_) returned no rows!");
- return rs.getInt(1)+1;
+ try {
+ if (!rs.next()) throw new RuntimeException("select max(uid_) returned no rows!");
+ return rs.getInt(1)+1;
+ } finally { db.close(rs); }
} catch (Exception e) { throw new RuntimeException(e); }
}
try {
Log.warn("SQL", "select count(*) from mail where " + whereClause);
ResultSet rs = conn.prepareStatement("select count(*) from mail where " + whereClause).executeQuery();
- rs.next();
- return rs.getInt(1);
+ try {
+ rs.next();
+ return rs.getInt(1);
+ } finally { db.close(rs); }
} catch (Exception e) { throw new RuntimeException(e); }
} catch (UnsupportedQueryException _) {
return super.count(q);
}
}
- public void insert(Message m, int flags) {
+ public synchronized void insert(Message m, int flags) {
try {
+
+ /*
PreparedStatement query = conn.prepareStatement("select headers_,body_,flags_ from 'mail' where messageid_=?");
query.setString(1, m.messageid);
Log.warn("SQL", "select headers_,body_,flags_ from 'mail' where messageid_="+m.messageid);
return;
}
}
+ */
PreparedStatement add =
conn.prepareStatement("insert "+/*"or replace "+*/"into 'mail' ("+columns+") values (?,?,?,?,?,?,?,?)");
add.setString(1, m.messageid+"");
rs = query.executeQuery();
} catch (Exception e) { throw new RuntimeException(e); }
}
+ public Headers head() {
+ if (m != null) return m.headers;
+ try {
+ PreparedStatement query = conn.prepareStatement("select headers_,flags_ from 'mail' where uid_=?");
+ query.setString(1, rs.getString(2));
+ Log.warn("SQL", "select headers_,flags_ from 'mail' where uid_="+rs.getString(2));
+
+ ResultSet rs2 = query.executeQuery();
+ if (!rs2.next()) { Log.error("XXX", "should not happen"); return null; }
+ flags = rs2.getInt(2);
+ return new Headers(Fountain.Util.create(rs2.getString(1)));
+ } catch (Exception e) { throw new RuntimeException(e); }
+ }
public Message cur() {
try {
if (m!=null) return m;
- PreparedStatement query = conn.prepareStatement("select headers_,body_,flags_ from 'mail' where messageid_=?");
- query.setString(1, rs.getString(1));
- Log.warn("SQL", "select headers_,body_,flags_ from 'mail' where messageid_="+rs.getString(1));
+ PreparedStatement query = conn.prepareStatement("select headers_,body_,flags_ from 'mail' where uid_=?");
+ query.setString(1, rs.getString(2));
+ Log.warn("SQL", "select headers_,body_,flags_ from 'mail' where uid_="+rs.getString(2));
ResultSet rs2 = query.executeQuery();
if (!rs2.next()) { Log.error("XXX", "should not happen"); return null; }
int oldflags = rs.getInt("flags_");
if (oldflags==flags) return;
Log.info(this, "setflags (old="+oldflags+")" + "update mail set flags_="+(flags)+" where uid_="+uid()+"");
+ if ((flags & Mailbox.Flag.DELETED) != 0) Log.printStackTrace("deletion", Log.WARN);
PreparedStatement update = conn.prepareStatement("update mail set flags_=? where uid_=?");
update.setInt(1, flags);
update.setInt(2, uid());
update.executeUpdate();
} catch (Exception e) { throw new RuntimeException(e); }
}
- public Headers head() { return cur().headers; }
public boolean next() {
try { m = null; uid = -1; count++;
boolean ret = rs.next();
}
public int imapNumber() {
if ("".equals(whereClause)) return count;
- try {
- ResultSet rs = conn.prepareStatement("select count(*) from mail where uid_ <= " + uid()).executeQuery();
- rs.next();
- return rs.getInt(1);
- } catch (Exception e) { throw new RuntimeException(e); }
+ try { return queryImapNumberCache(uid()); } catch (SQLException s) { throw new RuntimeException(s); }
}
public int nntpNumber() { return uid(); }
public void delete() {