cvsimport
[beagle.git] / beagled / EvolutionMailDriver / EvolutionSummaryTracker.cs
bloba24ddbc1a7ed2d25ac726bdce31c87c604f8ebd3
1 //
2 // EvolutionSummaryTracker.cs
3 //
4 // Copyright (C) 2006 Novell, Inc.
5 //
6 //
7 //
8 // Permission is hereby granted, free of charge, to any person obtaining a
9 // copy of this software and associated documentation files (the "Software"),
10 // to deal in the Software without restriction, including without limitation
11 // the rights to use, copy, modify, merge, publish, distribute, sublicense,
12 // and/or sell copies of the Software, and to permit persons to whom the
13 // Software is furnished to do so, subject to the following conditions:
15 // The above copyright notice and this permission notice shall be included in
16 // all copies or substantial portions of the Software.
18 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
23 // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
24 // DEALINGS IN THE SOFTWARE.
27 using System;
28 using System.Collections;
29 using System.IO;
31 using Mono.Data.SqliteClient;
33 using Beagle.Util;
35 namespace Beagle.Daemon.EvolutionMailDriver {
37 public class EvolutionSummaryTracker : IDisposable {
39 private SqliteConnection connection;
40 private string tmp_filename;
42 public EvolutionSummaryTracker (string directory, string account_name, string folder_name)
44 string filename = Path.Combine (directory, String.Format ("SummaryTracker-{0}-{1}.db", account_name, folder_name.Replace ('/', '-')));
45 bool create_new_db = ! File.Exists (filename);
47 tmp_filename = filename;
49 connection = GetConnection (filename);
50 try {
51 connection.Open ();
52 } catch (ApplicationException) {
53 create_new_db = true;
54 connection.Dispose ();
56 // Purge the old database and create a new one
57 File.Delete (filename);
58 connection = GetConnection (filename);
59 connection.Open ();
62 if (create_new_db)
63 CreateDatabase ();
65 // Start a transaction for any updates
66 SqliteUtils.DoNonQuery (connection, "BEGIN");
69 private static SqliteConnection GetConnection (string filename)
71 SqliteConnection connection = new SqliteConnection ();
72 connection.ConnectionString = String.Format ("version={0},encoding=UTF-8,URI=file:{1}", ExternalStringsHack.SqliteVersion, filename);
74 return connection;
77 private void CreateDatabase ()
79 SqliteUtils.DoNonQuery (connection,
80 "CREATE TABLE mapping ( " +
81 " uid STRING UNIQUE, " +
82 " flags INTEGER NOT NULL, " +
83 " last_seen STRING NOT NULL " +
84 ")");
86 SqliteUtils.DoNonQuery (connection,
87 "CREATE INDEX mapping_uid on mapping (uid)");
90 public void Checkpoint ()
92 lock (connection) {
93 // Commit any outstanding changes and open a new transaction
94 SqliteUtils.DoNonQuery (connection, "COMMIT");
95 SqliteUtils.DoNonQuery (connection, "BEGIN");
99 public void Close ()
101 lock (connection) {
102 // Commit any outstanding changes
103 SqliteUtils.DoNonQuery (connection, "COMMIT");
105 connection.Close ();
106 connection = null;
110 public void Dispose ()
112 Close ();
113 GC.SuppressFinalize (this);
116 public void Update (string uid, uint flags)
118 lock (connection) {
119 SqliteUtils.DoNonQuery (connection,
120 "INSERT OR REPLACE INTO mapping " +
121 " (uid, flags, last_seen) " +
122 " VALUES ('{0}', {1}, {2})",
123 uid.Replace ("'", "''"),
124 flags,
125 StringFu.DateTimeToString (DateTime.UtcNow));
129 public bool Get (string uid, out uint flags)
131 SqliteCommand command;
132 SqliteDataReader reader;
134 lock (connection) {
135 command = new SqliteCommand ();
136 command.Connection = connection;
137 command.CommandText = String.Format (
138 "SELECT flags FROM mapping WHERE uid='{0}'",
139 uid.Replace ("'", "''"));
141 reader = SqliteUtils.ExecuteReaderOrWait (command);
143 try {
144 if (SqliteUtils.ReadOrWait (reader)) {
145 flags = (uint) reader.GetInt32 (0);
146 return true;
147 } else {
148 flags = 0;
149 return false;
151 } finally {
152 reader.Close ();
153 command.Dispose ();
158 public void Remove (string uid)
160 lock (connection) {
161 SqliteUtils.DoNonQuery (connection,
162 "DELETE FROM mapping WHERE uid='{0}'",
163 uid.Replace ("'", "''"));
167 // FIXME: I don't really like this, the collection could be huge
168 public ArrayList GetOlderThan (DateTime dt)
170 SqliteCommand command;
171 SqliteDataReader reader;
173 lock (connection) {
174 command = new SqliteCommand ();
175 command.Connection = connection;
176 command.CommandText =
177 "SELECT uid FROM mapping WHERE last_seen < " +
178 StringFu.DateTimeToString (dt);
180 reader = SqliteUtils.ExecuteReaderOrWait (command);
182 ArrayList uids = new ArrayList ();
184 while (SqliteUtils.ReadOrWait (reader))
185 uids.Add (reader.GetString (0));
187 reader.Close ();
188 command.Dispose ();
190 return uids;