summaryrefslogtreecommitdiffstats
path: root/comm/mailnews/base/public/nsIMsgPluggableStore.idl
blob: 5273d6f0a6147f3cd85ab497644f5e89d0525ebd (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

#include "nsISupports.idl"

interface nsIMsgFolder;
interface nsIMsgCopyServiceListener;
interface nsIMsgDBHdr;
interface nsIMsgWindow;
interface nsIOutputStream;
interface nsIInputStream;
interface nsIUrlListener;
interface nsIMsgDatabase;
interface nsITransaction;

[scriptable, uuid(F732CE58-E540-4dc4-B803-9456056EBEFC)]

/**
 * Pluggable message store interface. Each incoming server can have a different
 * message store.
 * All methods are synchronous unless otherwise specified.
 */
interface nsIMsgPluggableStore : nsISupports {
  /**
   * Examines the store and adds subfolders for the existing folders in the
   * profile directory. aParentFolder->AddSubfolder is the normal way
   * to register the subfolders. This method is expected to be synchronous.
   * This shouldn't be confused with server folder discovery, which is allowed
   * to be asynchronous.
   *
   * @param aParentFolder folder whose existing children we want to discover.
   *                      This will be the root folder for the server object.
   * @param aDeep true if we should discover all descendents. Would we ever
   *              not want to do this?
   */

  void discoverSubFolders(in nsIMsgFolder aParentFolder, in boolean aDeep);
  /**
   * Creates storage for a new, empty folder.
   *
   * @param aParent parent folder
   * @param aFolderName leaf name of folder.
   * @return newly created folder.
   * @exception NS_MSG_FOLDER_EXISTS If the child exists.
   * @exception NS_MSG_CANT_CREATE_FOLDER for other errors.
   */
  nsIMsgFolder createFolder(in nsIMsgFolder aParent, in AString aFolderName);

  /**
   * Delete storage for a folder and its subfolders, if any.
   * This is a real delete, not a move to the trash folder.
   *
   * @param aFolder folder to delete
   */
  void deleteFolder(in nsIMsgFolder aFolder);

  /**
   * Rename storage for an existing folder.
   *
   * @param aFolder folder to rename
   * @param aNewName name to give new folder
   * @return the renamed folder object
   */
  nsIMsgFolder renameFolder(in nsIMsgFolder aFolder, in AString aNewName);

  /**
   * Tells if the store has the requested amount of space available in the
   * specified folder.
   *
   * @param aFolder folder we want to add messages to.
   * @param aSpaceRequested How many bytes we're trying to add to the store.
   *
   * The function returns an exception if there is not enough space to
   * indicate the reason of the shortage:
   * NS_ERROR_FILE_TOO_BIG   = the store cannot grow further due to internal limits
   * NS_ERROR_FILE_NO_DEVICE_SPACE = there is not enough space on the disk
   */
  boolean hasSpaceAvailable(in nsIMsgFolder aFolder,
                            in long long aSpaceRequested);

  /**
   * Move/Copy a folder to a new parent folder. This method is asynchronous.
   * The store needs to use the aListener to notify the core code of the
   * completion of the operation. And it must send the appropriate
   * nsIMsgFolderNotificationService notifications.
   *
   * @param aSrcFolder folder to move/copy
   * @param aDstFolder parent dest folder
   * @param aIsMoveFolder true if move, false if copy. If move, source folder
   *                      is deleted when copy completes.
   * @param aMsgWindow used to display progress, may be null
   * @param aListener - used to get notification when copy is done.
   * @param aNewName  Optional new name for the target folder.
   *                  If rename is not needed, set this to empty string.
   */
  void copyFolder(in nsIMsgFolder aSrcFolder, in nsIMsgFolder aDstFolder,
                  in boolean aIsMoveFolder, in nsIMsgWindow aMsgWindow,
                  in nsIMsgCopyServiceListener aListener,
                  in AString aNewName);

  /**
   * Get an output stream for a message in a folder.
   *
   * @param aFolder folder to create a message output stream for.
   * @param aNewHdr If aNewHdr is set on input, then this is probably for
   *                offline storage of an existing message. If null, the
   *                this is a newly downloaded message and the store needs
   *                to create a new header for the new message. If the db
   *                is invalid, this can be null. But if the db is valid,
   *                the store should create a message header with the right
   *                message key, or whatever other property it needs to set to
   *                be able to retrieve the message contents later. If the store
   *                needs to base any of this on the contents of the message,
   *                it will need remember the message header and hook into
   *                the output stream somehow to alter the message header.
   *
   * @return The output stream to write to. The output stream will be positioned
   *         for writing (e.g., for berkeley mailbox, it will be at the end).
   */
  nsIOutputStream getNewMsgOutputStream(in nsIMsgFolder aFolder,
                                        inout nsIMsgDBHdr aNewHdr);


  /**
   * Called when the current message is discarded, e.g., it is moved
   * to an other folder as a filter action, or is deleted because it's
   * a duplicate. This gives the berkeley mailbox store a chance to simply
   * truncate the Inbox w/o leaving a deleted message in the store.
   *
   * discardNewMessage closes aOutputStream always unless the passed stream
   * is nullptr due to error processing..
   * (Clarification/Rationale in Bug 1121842, 1122698, 1242030)
   *
   * @param aOutputStream stream we were writing the message to be discarded to
   * @param aNewHdr header of message to discard
   */
  void discardNewMessage(in nsIOutputStream aOutputStream,
                         in nsIMsgDBHdr aNewHdr);

  /**
   * Must be called by code that calls getNewMsgOutputStream to finish
   * the process of storing a new message, if the new msg has not been
   * discarded. Could/should this be combined with discardNewMessage?
   *
   * finishNewMessage closes aOutputStream always unless the passed stream
   * is nullptr due to error processing.
   * (Clarification/Rationale in Bug 1121842, 1122698, 1242030)
   *
   * @param aOutputStream stream we were writing the message to.
   * @param aNewHdr header of message finished.
   */
  void finishNewMessage(in nsIOutputStream aOutputStream,
                        in nsIMsgDBHdr aNewHdr);

  /**
   * Called by pop3 message filters when a newly downloaded message is being
   * moved by an incoming filter. This is called before finishNewMessage, and
   * it allows the store to optimize that case.
   *
   * @param aNewHdr msg hdr of message being moved.
   * @param aDestFolder folder to move message to, in the same store.
   *
   * @return true if successful, false if the store doesn't want to optimize
   *         this.
   * @exception If the moved failed. values TBD
   */
  boolean moveNewlyDownloadedMessage(in nsIMsgDBHdr aNewHdr,
                                     in nsIMsgFolder aDestFolder);

  /**
   * Get an input stream that we can read the contents of a message from.
   *
   * @param aMsgFolder Folder containing the message
   * @param aMsgToken token that identifies message. This is store-dependent,
   *                  and must be set as a string property "storeToken" on the
   *                  message hdr by the store when the message is added
   *                  to the store.
   */
  nsIInputStream getMsgInputStream(in nsIMsgFolder aFolder,
                                   in ACString aMsgToken);

  /**
   * This is a hack to expose to allow JsAccount folders to implement a
   * working getLocalMsgStream().
   * It just provides a way to construct a SlicedInputStream from JS.
   * It'll be removed once Bug 1733849 is complete.
   *
   * @param inStream The stream providing the data to be sliced.
   *                 Should not be read after calling this function.
   * @param start Where slice begins, from current position of inStream.
   * @param length The size of the slice.
   *
   * @return A new input stream which produces the data slice when read from.
   */
  nsIInputStream sliceStream(in nsIInputStream inStream,
                             in unsigned long long start,
                             in unsigned long length);

  /**
   * Delete the passed in messages. These message should all be in the
   * same folder.
   * @param aHdrArray array of nsIMsgDBHdr's.
   */
  void deleteMessages(in Array<nsIMsgDBHdr> aHdrArray);

  /**
   * This allows the store to handle a msg move/copy if it wants. This lets
   * it optimize move/copies within the same store. E.g., for maildir, a
   * msg move mostly entails moving the file containing the message, and
   * updating the db.
   * If the store does the copy, it must return the appropriate undo action,
   * which can be store dependent. And it must send the appropriate
   * nsIMsgFolderNotificationService notifications.
   * If the store does not perform the copy, it returns false and the caller
   * has to handle the copy itself (by streaming messages).
   * This function is synchronous.
   *
   * @param isMove true if this is a move, false if it is a copy.
   * @param aHdrArray array of nsIMsgDBHdr's, all in the same folder
   * @param aDstFolder folder to move/copy the messages to.
   * @param aDstHdrs array of nsIMsgDBHdr's in the destination folder.
   * @param[out,optional] aUndoAction transaction to provide undo, if
   * the store does the copy itself.
   * @return true if messages were copied, false if the core code should
   *         do the copy.
   */
  boolean copyMessages(in boolean isMove,
                       in Array<nsIMsgDBHdr> aHdrArray,
                       in nsIMsgFolder aDstFolder,
                       out Array<nsIMsgDBHdr> aDstHdrs,
                       out nsITransaction aUndoAction);

  /**
   * Does this store require compaction? For example, maildir doesn't require
   * compaction at all. Berkeley mailbox does. A sqlite store probably doesn't.
   * This is a static property of the store. It doesn't mean that any particular
   * folder has space that can be reclaimed via compaction. Right now, the core
   * code keeps track of the size of messages deleted, which it can use in
   * conjunction with this store attribute.
   */
  readonly attribute boolean supportsCompaction;

  /**
   * Remove deleted messages from the store, reclaiming space. Some stores
   * won't need to do anything here (e.g., maildir), and those stores
   * should return false for needsCompaction. This operation is asynchronous,
   * and the passed url listener should be called when the operation is done.
   *
   * @param aFolder folder whose storage is to be compacted
   * @param aListener listener notified when compaction is done.
   * @param aMsgWindow window to display progress/status in.
   */
  void compactFolder(in nsIMsgFolder aFolder, in nsIUrlListener aListener,
                     in nsIMsgWindow aMsgWindow);

  /**
   * Is the summary file for the passed folder valid? For Berkeley Mailboxes,
   * for local mail folders, this checks the timestamp and size of the local
   * mail folder against values stored in the db. For other stores, this may
   * be a noop, though other stores could certainly become invalid. For
   * Berkeley Mailboxes, this is to deal with the case of other apps altering
   * mailboxes from outside mailnews code, and this is certainly possible
   * with other stores.
   *
   * @param aFolder Folder to check if summary is valid for.
   * @param aDB DB to check validity of.
   *
   * @return return true if the summary file is valid, false otherwise.
   */
  boolean isSummaryFileValid(in nsIMsgFolder aFolder, in nsIMsgDatabase aDB);

  /**
   * Marks the summary file for aFolder as valid or invalid. This method
   * may not be required, since it's really used by Berkeley Mailbox code
   * to fix the timestamp and size for a folder.
   *
   * @param aFolder folder whose summary file should be marked (in)valid.
   * @param aDB db to mark valid (may not be the folder's db in odd cases
   *            like folder compaction.
   * @param aValid whether to mark it valid or invalid.
   */
  void setSummaryFileValid(in nsIMsgFolder aFolder, in nsIMsgDatabase aDB,
                           in boolean aValid);

  /**
   * Rebuild the index from information in the store. This involves creating
   * a new nsIMsgDatabase for the folder, adding the information for all the
   * messages in the store, and then copying the new msg database over the
   * existing database. For Berkeley mailbox, we try to maintain meta data
   * stored in the existing database when possible, and other stores should do
   * the same. Ideally, I would figure out a way of making that easy. That
   * might entail reworking the rebuild index process into one where the store
   * would iterate over the messages, and stream each message through the
   * message parser, and the common code would handle maintaining the
   * meta data. But the berkeley mailbox code needs to do some parsing because
   * it doesn't know how big the message is (i.e., the stream can't simply be
   * a file stream).
   * This operation is asynchronous,
   * and the passed url listener should be called when the operation is done.
   *
   * @param aFolder folder whose storage is to be compacted
   * @param aMsgDB db to put parsed headers in.
   * @param aMsgWindow msgWindow to use for progress updates.
   * @param aListener listener notified when the index is rebuilt.
   */
  void rebuildIndex(in nsIMsgFolder aFolder, in nsIMsgDatabase aMsgDB,
                    in nsIMsgWindow aMsgWindow, in nsIUrlListener aListener);

  /**
   * Sets/Clears the passed flags on the passed messages.
   * @param aHdrArray array of nsIMsgDBHdr's
   * @param aFlags flags to set/clear
   * @param aSet true to set the flag(s), false to clear.
   */
  void changeFlags(in Array<nsIMsgDBHdr> aHdrArray, in unsigned long aFlags,
                   in boolean aSet);
  /**
   *Sets/Clears the passed keywords on the passed messages.
   * @param aHdrArray array of nsIMsgDBHdr's
   * @param aKeywords keywords to set/clear
   * @param aAdd true to add the keyword(s), false to remove.
   */
  void changeKeywords(in Array<nsIMsgDBHdr> aHdrArray, in ACString aKeywords,
                      in boolean aAdd);

  /**
   * Identifies a specific type of store. Please use this only for legacy
   * bug fixes, and not as a method to change behavior!
   *
   * Typical values: "mbox", "maildir"
   */
  readonly attribute ACString storeType;
};