handle more types of Query in SqliteMailbox
authoradam <adam@megacz.com>
Sat, 1 Mar 2008 07:43:46 +0000 (07:43 +0000)
committeradam <adam@megacz.com>
Sat, 1 Mar 2008 07:43:46 +0000 (07:43 +0000)
darcs-hash:20080301074346-5007d-8c9bac86e780f9c1fbcad347ef7e380295dce135.gz

src/org/ibex/mail/SqliteMailbox.java

index c880f75..bcea924 100644 (file)
@@ -120,7 +120,8 @@ public class SqliteMailbox extends Mailbox.Default implements MailTree {
         try {
             PreparedStatement q = conn.prepareStatement("select max(uid_) from mail");
             ResultSet rs = q.executeQuery();
-            if (!rs.next()) return -1;
+            //if (!rs.next()) return -1;
+            if (!rs.next()) throw new RuntimeException("select max(uid_) returned no rows!");
             return rs.getInt(1)+1;
         } catch (Exception e) { throw new RuntimeException(e); }
     }
@@ -145,23 +146,24 @@ public class SqliteMailbox extends Mailbox.Default implements MailTree {
         }
         return whereClause;
     }
-    private static String joinWith(String op, Query[] q) throws UnsupportedQueryException {
-        boolean add = false;
-        StringBuffer sb = new StringBuffer();
-        for(int i=0; i<q.length; i++) {
-            if (add) sb.append(" " + op);
-            sb.append(" (");
-            sb.append(getWhereClause(q[i]));
-            sb.append(")");
-            add = true;
-        }
-        return sb.toString();
-    }
-    private static String getWhereClause(Query q) throws UnsupportedQueryException {
+    private String getWhereClause(Query q) throws UnsupportedQueryException {
+        String op;
         switch(q.type) {
             case Query.NOT:      return "not ("+getWhereClause(q.q[0])+")";
-            case Query.AND:      return joinWith("and", q.q);
-            case Query.OR:       return joinWith("or", q.q);
+            case Query.AND:      op = "and";
+            case Query.OR:       op = "or";
+                {
+                    boolean add = false;
+                    StringBuffer sb = new StringBuffer();
+                    for(int i=0; i<q.q.length; i++) {
+                        if (add) sb.append(" " + op);
+                        sb.append(" (");
+                        sb.append(getWhereClause(q.q[i]));
+                        sb.append(")");
+                        add = true;
+                    }
+                    return sb.toString();
+                }
             case Query.ALL:      return "1=1";
             case Query.UID:      return set(q.set, "uid_");
             case Query.DELETED:  return "((flags_ & "+(Mailbox.Flag.DELETED)+")!=0)";
@@ -179,8 +181,32 @@ public class SqliteMailbox extends Mailbox.Default implements MailTree {
                 public static final int FULL       = 10;
                 public static final int IMAPNUM    = 11;
                 */
+
+            case Query.IMAPNUM: {
+                try {
+                    // translate queries in terms of imap numbers into queries in terms of uids
+                    // RELIES ON THE FACT THAT UIDS ARE MONOTONICALLY INCREASING
+                    int[] set = new int[q.set==null ? 2 : q.set.length];
+                    if (q.set==null) { set[0] = q.min; set[1] = q.max; }
+                    else System.arraycopy(q.set, 0, set, 0, q.set.length);
+                    for(int i=0; i<set.length; i++) {
+                        int uid = queryUidForImapNum(set[i]);
+                        if (uid==-1) {
+                            Log.info(SqliteMailbox.class, "PROBLEM => resorting to superclass: " + q);
+                            throw new UnsupportedQueryException();
+                        }
+                        set[i] = uid;
+                    }
+                    return getWhereClause(Query.uid(set));
+                } catch (SQLException e) {
+                    Log.error(this, e);
+                    Log.info(SqliteMailbox.class, "resorting to superclass: " + q);
+                    throw new UnsupportedQueryException();
+                }
+            }
+
             default: {
-                Log.info(SqliteMailbox.class, "resorting to superclass: " + q.type);
+                Log.info(SqliteMailbox.class, "resorting to superclass: " + q);
                 throw new UnsupportedQueryException();
             }
         }
@@ -200,6 +226,7 @@ public class SqliteMailbox extends Mailbox.Default implements MailTree {
             String whereClause = getWhereClause(q);
             Log.info(this, "whereClause = " + whereClause);
             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);
@@ -239,6 +266,7 @@ public class SqliteMailbox extends Mailbox.Default implements MailTree {
         public SqliteJdbcIterator(String whereClause) {
             try {
                 this.whereClause = whereClause;
+                Log.warn("SQL", "select messageid_,uid_,flags_ from 'mail' "+whereClause);
                 PreparedStatement query = conn.prepareStatement("select messageid_,uid_,flags_ from 'mail' "+whereClause);
                 rs = query.executeQuery();
             } catch (Exception e) { throw new RuntimeException(e); }
@@ -248,6 +276,7 @@ public class SqliteMailbox extends Mailbox.Default implements MailTree {
                 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));
 
                 ResultSet rs2 = query.executeQuery();
                 if (!rs2.next()) { Log.error("XXX", "should not happen"); return null; }
@@ -294,6 +323,9 @@ public class SqliteMailbox extends Mailbox.Default implements MailTree {
         public int     nntpNumber() { return uid(); }
         public void    delete()     {
             try {
+                Log.error("sqlite", "actually deleting message "+uid()+" "+head().get("subject"));
+                Log.printStackTrace("sqlite", Log.ERROR);
+
                 PreparedStatement update = conn.prepareStatement("delete from mail where uid_=?");
                 update.setInt(1, uid());
                 update.executeUpdate();