reshuffling of file locations to make package structure flatter
[org.ibex.mail.git] / src / org / ibex / mail / SqliteJdbcMailbox.java
1 package org.ibex.mail;
2
3 import org.ibex.io.Fountain;
4 import org.ibex.io.Stream;
5 import java.sql.Timestamp;
6 import java.sql.*;
7 import java.net.*;
8 import java.io.*;
9 import java.util.*;
10
11 // nntpNumber (column)
12 // uid (column)
13 // uidvalidity
14 public class SqliteJdbcMailbox extends Mailbox.Default {
15
16     private Connection conn;
17     private static final String columns = "messageid_,from_,to_,date_,subject_,headers_,body_,flags_";
18
19     public SqliteJdbcMailbox(String filename) {
20         try {
21             Class.forName("org.sqlite.JDBC");
22             conn = DriverManager.getConnection("jdbc:sqlite:"+filename);
23             conn.prepareStatement("create virtual table if not exists "+
24                                   "'mail' using FTS1("+columns+",PRIMARY KEY(messageid_))").executeUpdate();
25         }
26         catch (SQLException e) { throw new RuntimeException(e); }
27         catch (ClassNotFoundException e) { throw new RuntimeException(e); }
28     }
29
30     public int              uidNext()                    { throw new RuntimeException("not supported"); }
31     public Mailbox.Iterator iterator()                   { return new SqliteJdbcIterator(); }
32     public void             insert(Message m, int flags) {
33         // FIXME: flags
34         try {
35             PreparedStatement add =
36                 conn.prepareStatement("insert into 'mail' ("+columns+") values (?,?,?,?,?,?,?,?)");
37             add.setString(1, m.messageid+"");
38             add.setString(2, m.from+"");
39             add.setString(3, m.to+"");
40             add.setString(4, m.date+"");
41             add.setString(5, m.subject+"");
42             add.setString(6, streamToString(m.headers.getStream()));
43             add.setString(7, streamToString(m.getBody().getStream()));
44             add.setInt   (8, flags);
45             add.executeUpdate();
46         } catch (Exception e) { throw new RuntimeException(e); }
47     }
48
49     private class SqliteJdbcIterator extends Mailbox.Default.Iterator {
50         // could be more efficient in a ton of ways
51         private ResultSet rs;
52         private int count  = 1;
53         private int flags;
54         private Message m  = null;
55         public SqliteJdbcIterator() {
56             try {
57                 PreparedStatement query = conn.prepareStatement("select messageid_ from 'mail'");
58                 rs = query.executeQuery();
59                 rs.next();
60             } catch (Exception e) { throw new RuntimeException(e); }
61         }
62         public Message cur()    {
63             try {
64                 if (m!=null) return m;
65                 rs.next();
66                 PreparedStatement query = conn.prepareStatement("select headers_,body_,flags_ from 'mail' where messageid_=?");
67                 query.setString(1, rs.getString(1));
68                 ResultSet rs2 = query.executeQuery();
69                 if (!rs.next()) return null;
70                 m = Message.newMessage(new Fountain.StringFountain(rs.getString(1) + "\r\n\r\n" + rs.getString(2)));
71                 flags = rs.getInt(3);
72                 return m;
73             } catch (Exception e) { throw new RuntimeException(e); }
74         }
75         public int     getFlags()   { if (m==null) /* could be more efficient */ cur(); return flags; }
76         public Headers head()       { return cur().headers; }
77         public boolean next()       { try { m = null; count++; return rs.next(); } catch (Exception e) { throw new RuntimeException(e); } }
78         public int     uid()        { throw new RuntimeException("not supported"); }
79         public int     imapNumber() { return count; }
80         public int     nntpNumber() { throw new RuntimeException("not supported"); }
81         public void    delete()     { throw new RuntimeException("not supported"); }
82     }
83
84     private static String streamToString(Stream stream) throws Exception {
85         StringBuffer b = new StringBuffer();
86         for(String s = stream.readln(); s!=null; s=stream.readln())
87             b.append(s+"\n");
88         return b.toString();
89     }
90
91 }