1 /*
2  * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
3  *
4  * This library is free software: you can redistribute it and/or modify it
5  * under the terms of the GNU Lesser General Public License as published by
6  * the Free Software Foundation.
7  *
8  * This library is distributed in the hope that it will be useful, but
9  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
10  * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
11  * for more details.
12  *
13  * You should have received a copy of the GNU Lesser General Public License
14  * along with this library. If not, see <http://www.gnu.org/licenses/>.
15  *
16  * Authors: Sankar P <psankar@novell.com>
17  *          Srinivasa Ragavan <sragavan@novell.com>
18  */
19 
20 #if !defined (__CAMEL_H_INSIDE__) && !defined (CAMEL_COMPILATION)
21 #error "Only <camel/camel.h> can be included directly."
22 #endif
23 
24 #ifndef CAMEL_DB_H
25 #define CAMEL_DB_H
26 
27 #include <glib.h>
28 #include <glib-object.h>
29 
30 /* Standard GObject macros */
31 #define CAMEL_TYPE_DB \
32 	(camel_db_get_type ())
33 #define CAMEL_DB(obj) \
34 	(G_TYPE_CHECK_INSTANCE_CAST \
35 	((obj), CAMEL_TYPE_DB, CamelDB))
36 #define CAMEL_DB_CLASS(cls) \
37 	(G_TYPE_CHECK_CLASS_CAST \
38 	((cls), CAMEL_TYPE_DB, CamelDBClass))
39 #define CAMEL_IS_DB(obj) \
40 	(G_TYPE_CHECK_INSTANCE_TYPE \
41 	((obj), CAMEL_TYPE_DB))
42 #define CAMEL_IS_DB_CLASS(obj) \
43 	(G_TYPE_CHECK_CLASS_TYPE \
44 	((cls), CAMEL_TYPE_DB))
45 #define CAMEL_DB_GET_CLASS(obj) \
46 	(G_TYPE_INSTANCE_GET_CLASS \
47 	((obj), CAMEL_TYPE_DB, CamelDBClass))
48 
49 G_BEGIN_DECLS
50 
51 typedef struct _CamelDB CamelDB;
52 typedef struct _CamelDBClass CamelDBClass;
53 typedef struct _CamelDBPrivate CamelDBPrivate;
54 
55 /**
56  * CamelDB:
57  *
58  * Since: 2.24
59  **/
60 struct _CamelDB {
61 	/*< private >*/
62 	GObject parent;
63 	CamelDBPrivate *priv;
64 };
65 
66 struct _CamelDBClass {
67 	/*< private >*/
68 	GObjectClass parent_class;
69 
70 	/* Padding for future expansion */
71 	gpointer reserved[20];
72 };
73 
74 /**
75  * CamelDBCollate:
76  * @enc: a used encoding (SQLITE_UTF8)
77  * @length1: length of the @data1
78  * @data1: the first value, of lenth @length1
79  * @length2: length of the @data2
80  * @data2: the second value, of lenth @length2
81  *
82  * A collation callback function.
83  *
84  * Returns: less than zero, zero, or greater than zero value, the same as for example strcmp() does.
85  *
86  * Since: 2.24
87  **/
88 typedef gint (* CamelDBCollate)(gpointer enc, gint length1, gconstpointer data1, gint length2, gconstpointer data2);
89 
90 /**
91  * CAMEL_DB_FILE:
92  *
93  * Since: 2.24
94  **/
95 #define CAMEL_DB_FILE "folders.db"
96 
97 /* Hopefully no one will create a folder named EVO_IN_meM_hAnDlE */
98 
99 /**
100  * CAMEL_DB_IN_MEMORY_TABLE:
101  *
102  * Since: 2.26
103  **/
104 #define CAMEL_DB_IN_MEMORY_TABLE "EVO_IN_meM_hAnDlE.temp"
105 
106 /**
107  * CAMEL_DB_IN_MEMORY_DB:
108  *
109  * Since: 2.26
110  **/
111 #define CAMEL_DB_IN_MEMORY_DB "EVO_IN_meM_hAnDlE"
112 
113 /**
114  * CAMEL_DB_IN_MEMORY_TABLE_LIMIT:
115  *
116  * Since: 2.26
117  **/
118 #define CAMEL_DB_IN_MEMORY_TABLE_LIMIT 100000
119 
120 
121 /**
122  * CAMEL_DB_FREE_CACHE_SIZE:
123  *
124  * Since: 2.24
125  **/
126 #define CAMEL_DB_FREE_CACHE_SIZE 2 * 1024 * 1024
127 
128 /**
129  * CAMEL_DB_SLEEP_INTERVAL:
130  *
131  * Since: 2.24
132  **/
133 #define CAMEL_DB_SLEEP_INTERVAL 1*10*10
134 
135 /**
136  * CamelMIRecord:
137  * @uid: Message UID
138  * @flags: Camel Message info flags
139  * @msg_type: unused
140  * @dirty: whether the message info requires upload to the server; it corresponds to #CAMEL_MESSAGE_FOLDER_FLAGGED
141  * @read: boolean read status
142  * @deleted: boolean deleted status
143  * @replied: boolean replied status
144  * @important: boolean important status
145  * @junk: boolean junk status
146  * @attachment: boolean attachment status
147  * @size: size of the mail
148  * @dsent: date sent
149  * @dreceived: date received
150  * @subject: subject of the mail
151  * @from: sender
152  * @to: recipient
153  * @cc: CC members
154  * @mlist: message list headers
155  * @followup_flag: followup flag / also can be queried to see for followup or not
156  * @followup_completed_on: completed date, can be used to see if completed
157  * @followup_due_by: to see the due by date
158  * @part: part / references / thread id
159  * @labels: labels of mails also called as userflags
160  * @usertags: composite string of user tags
161  * @cinfo: content info string - composite string
162  * @bdata: provider specific data
163  * @userheaders: value for user-defined message headers; Since: 3.42
164  * @preview: message body preview; Since: 3.42
165  *
166  * The extensive DB format, supporting basic searching and sorting.
167  *
168  * Since: 2.24
169  **/
170 typedef struct _CamelMIRecord {
171 	const gchar *uid; /* stored in the string pool */
172 	guint32 flags;
173 	guint32 msg_type;
174 	guint32 dirty;
175 	gboolean read;
176 	gboolean deleted;
177 	gboolean replied;
178 	gboolean important;
179 	gboolean junk;
180 	gboolean attachment;
181 	guint32 size;
182 	gint64 dsent; /* time_t */
183 	gint64 dreceived; /* time_t */
184 	const gchar *subject;	/* stored in the string pool */
185 	const gchar *from;	/* stored in the string pool */
186 	const gchar *to;	/* stored in the string pool */
187 	const gchar *cc;	/* stored in the string pool */
188 	const gchar *mlist;	/* stored in the string pool */
189 	gchar *followup_flag;
190 	gchar *followup_completed_on;
191 	gchar *followup_due_by;
192 	gchar *part;
193 	gchar *labels;
194 	gchar *usertags;
195 	gchar *cinfo;
196 	gchar *bdata;
197 	gchar *userheaders;
198 	gchar *preview;
199 } CamelMIRecord;
200 
201 /**
202  * CamelFIRecord:
203  * @folder_name: name of the folder
204  * @version: version of the saved information
205  * @flags: folder flags
206  * @nextuid: next free uid
207  * @timestamp: timestamp of the summary
208  * @saved_count: count of all messages
209  * @unread_count: count of unread messages
210  * @deleted_count: count of deleted messages
211  * @junk_count: count of junk messages
212  * @visible_count: count of visible (not deleted and not junk) messages
213  * @jnd_count: count of junk and not deleted messages
214  * @bdata: custom data of the #CamelFolderSummary descendants
215  *
216  * Values to store/load for single folder's #CamelFolderSummary structure.
217  *
218  * Since: 2.24
219  **/
220 typedef struct _CamelFIRecord {
221 	gchar *folder_name;
222 	guint32 version;
223 	guint32 flags;
224 	guint32 nextuid;
225 	gint64 timestamp;
226 	guint32 saved_count;
227 	guint32 unread_count;
228 	guint32 deleted_count;
229 	guint32 junk_count;
230 	guint32 visible_count;
231 	guint32 jnd_count;  /* Junked not deleted */
232 	gchar *bdata;
233 } CamelFIRecord;
234 
235 /**
236  * CamelDBKnownColumnNames:
237  * @CAMEL_DB_COLUMN_UNKNOWN: unknown column name
238  * @CAMEL_DB_COLUMN_ATTACHMENT: attachment
239  * @CAMEL_DB_COLUMN_BDATA: bdata
240  * @CAMEL_DB_COLUMN_CINFO: cinfo
241  * @CAMEL_DB_COLUMN_DELETED: deleted
242  * @CAMEL_DB_COLUMN_DELETED_COUNT: deleted_count
243  * @CAMEL_DB_COLUMN_DRECEIVED: dreceived
244  * @CAMEL_DB_COLUMN_DSENT: dsent
245  * @CAMEL_DB_COLUMN_FLAGS: flags
246  * @CAMEL_DB_COLUMN_FOLDER_NAME: folder_name
247  * @CAMEL_DB_COLUMN_FOLLOWUP_COMPLETED_ON: followup_completed_on
248  * @CAMEL_DB_COLUMN_FOLLOWUP_DUE_BY: followup_due_by
249  * @CAMEL_DB_COLUMN_FOLLOWUP_FLAG: followup_flag
250  * @CAMEL_DB_COLUMN_IMPORTANT: important
251  * @CAMEL_DB_COLUMN_JND_COUNT: jnd_count
252  * @CAMEL_DB_COLUMN_JUNK: junk
253  * @CAMEL_DB_COLUMN_JUNK_COUNT: junk_count
254  * @CAMEL_DB_COLUMN_LABELS: labels
255  * @CAMEL_DB_COLUMN_MAIL_CC: mail_cc
256  * @CAMEL_DB_COLUMN_MAIL_FROM: mail_from
257  * @CAMEL_DB_COLUMN_MAIL_TO: mail_to
258  * @CAMEL_DB_COLUMN_MLIST: mlist
259  * @CAMEL_DB_COLUMN_NEXTUID: nextuid
260  * @CAMEL_DB_COLUMN_PART: part
261  * @CAMEL_DB_COLUMN_PREVIEW: preview
262  * @CAMEL_DB_COLUMN_READ: read
263  * @CAMEL_DB_COLUMN_REPLIED: replied
264  * @CAMEL_DB_COLUMN_SAVED_COUNT: saved_count
265  * @CAMEL_DB_COLUMN_SIZE: size
266  * @CAMEL_DB_COLUMN_SUBJECT: subject
267  * @CAMEL_DB_COLUMN_TIME: time
268  * @CAMEL_DB_COLUMN_UID: uid
269  * @CAMEL_DB_COLUMN_UNREAD_COUNT: unread_count
270  * @CAMEL_DB_COLUMN_USERHEADERS: userheaders
271  * @CAMEL_DB_COLUMN_USERTAGS: usertags
272  * @CAMEL_DB_COLUMN_VERSION: version
273  * @CAMEL_DB_COLUMN_VISIBLE_COUNT: visible_count
274  * @CAMEL_DB_COLUMN_VUID: vuid
275  *
276  * An enum of all the known columns, which can be used for a quick column lookups.
277  *
278  * Since: 3.4
279  **/
280 typedef enum {
281 	CAMEL_DB_COLUMN_UNKNOWN = -1,
282 	CAMEL_DB_COLUMN_ATTACHMENT,
283 	CAMEL_DB_COLUMN_BDATA,
284 	CAMEL_DB_COLUMN_CINFO,
285 	CAMEL_DB_COLUMN_DELETED,
286 	CAMEL_DB_COLUMN_DELETED_COUNT,
287 	CAMEL_DB_COLUMN_DRECEIVED,
288 	CAMEL_DB_COLUMN_DSENT,
289 	CAMEL_DB_COLUMN_FLAGS,
290 	CAMEL_DB_COLUMN_FOLDER_NAME,
291 	CAMEL_DB_COLUMN_FOLLOWUP_COMPLETED_ON,
292 	CAMEL_DB_COLUMN_FOLLOWUP_DUE_BY,
293 	CAMEL_DB_COLUMN_FOLLOWUP_FLAG,
294 	CAMEL_DB_COLUMN_IMPORTANT,
295 	CAMEL_DB_COLUMN_JND_COUNT,
296 	CAMEL_DB_COLUMN_JUNK,
297 	CAMEL_DB_COLUMN_JUNK_COUNT,
298 	CAMEL_DB_COLUMN_LABELS,
299 	CAMEL_DB_COLUMN_MAIL_CC,
300 	CAMEL_DB_COLUMN_MAIL_FROM,
301 	CAMEL_DB_COLUMN_MAIL_TO,
302 	CAMEL_DB_COLUMN_MLIST,
303 	CAMEL_DB_COLUMN_NEXTUID,
304 	CAMEL_DB_COLUMN_PART,
305 	CAMEL_DB_COLUMN_PREVIEW,
306 	CAMEL_DB_COLUMN_READ,
307 	CAMEL_DB_COLUMN_REPLIED,
308 	CAMEL_DB_COLUMN_SAVED_COUNT,
309 	CAMEL_DB_COLUMN_SIZE,
310 	CAMEL_DB_COLUMN_SUBJECT,
311 	CAMEL_DB_COLUMN_TIME,
312 	CAMEL_DB_COLUMN_UID,
313 	CAMEL_DB_COLUMN_UNREAD_COUNT,
314 	CAMEL_DB_COLUMN_USERHEADERS,
315 	CAMEL_DB_COLUMN_USERTAGS,
316 	CAMEL_DB_COLUMN_VERSION,
317 	CAMEL_DB_COLUMN_VISIBLE_COUNT,
318 	CAMEL_DB_COLUMN_VUID
319 } CamelDBKnownColumnNames;
320 
321 CamelDBKnownColumnNames camel_db_get_column_ident (GHashTable **hash, gint index, gint ncols, gchar **col_names);
322 
323 /**
324  * CamelDBSelectCB:
325  * @user_data: a callback user data
326  * @ncol: how many columns is provided
327  * @colvalues: (array length=ncol): array of column values, as UTF-8 strings
328  * @colnames: (array length=ncol): array of column names
329  *
330  * A callback called for the SELECT statements. The items at the same index of @colvalues
331  * and @colnames correspond to each other.
332  *
333  * Returns: 0 to continue the SELECT execution, non-zero to abort the execution.
334  *
335  * Since: 2.24
336  **/
337 typedef gint (* CamelDBSelectCB) (gpointer user_data, gint ncol, gchar **colvalues, gchar **colnames);
338 
339 GType		camel_db_get_type		(void) G_GNUC_CONST;
340 
341 CamelDB *	camel_db_new			(const gchar *filename,
342 						 GError **error);
343 const gchar *	camel_db_get_filename		(CamelDB *cdb);
344 gint		camel_db_command		(CamelDB *cdb,
345 						 const gchar *stmt,
346 						 GError **error);
347 gint		camel_db_transaction_command	(CamelDB *cdb,
348 						 const GList *qry_list,
349 						 GError **error);
350 gint		camel_db_begin_transaction	(CamelDB *cdb,
351 						 GError **error);
352 gint		camel_db_add_to_transaction	(CamelDB *cdb,
353 						 const gchar *query,
354 						 GError **error);
355 gint		camel_db_end_transaction	(CamelDB *cdb,
356 						 GError **error);
357 gint		camel_db_abort_transaction	(CamelDB *cdb,
358 						 GError **error);
359 gint		camel_db_clear_folder_summary	(CamelDB *cdb,
360 						 const gchar *folder_name,
361 						 GError **error);
362 gint		camel_db_rename_folder		(CamelDB *cdb,
363 						 const gchar *old_folder_name,
364 						 const gchar *new_folder_name,
365 						 GError **error);
366 gint		camel_db_delete_folder		(CamelDB *cdb,
367 						 const gchar *folder_name,
368 						 GError **error);
369 gint		camel_db_delete_uid		(CamelDB *cdb,
370 						 const gchar *folder_name,
371 						 const gchar *uid,
372 						 GError **error);
373 gint		camel_db_delete_uids		(CamelDB *cdb,
374 						 const gchar *folder_name,
375 						 const GList *uids,
376 						 GError **error);
377 gint		camel_db_create_folders_table	(CamelDB *cdb,
378 						 GError **error);
379 gint		camel_db_select			(CamelDB *cdb,
380 						 const gchar *stmt,
381 						 CamelDBSelectCB callback,
382 						 gpointer user_data,
383 						 GError **error);
384 gint		camel_db_write_folder_info_record
385 						(CamelDB *cdb,
386 						 CamelFIRecord *record,
387 						 GError **error);
388 gint		camel_db_read_folder_info_record
389 						(CamelDB *cdb,
390 						 const gchar *folder_name,
391 						 CamelFIRecord *record,
392 						 GError **error);
393 gint		camel_db_prepare_message_info_table
394 						(CamelDB *cdb,
395 						 const gchar *folder_name,
396 						 GError **error);
397 gint		camel_db_write_message_info_record
398 						(CamelDB *cdb,
399 						 const gchar *folder_name,
400 						 CamelMIRecord *record,
401 						 GError **error);
402 gint		camel_db_read_message_info_records
403 						(CamelDB *cdb,
404 						 const gchar *folder_name,
405 						 gpointer user_data,
406 						 CamelDBSelectCB callback,
407 						 GError **error);
408 gint		camel_db_read_message_info_record_with_uid
409 						(CamelDB *cdb,
410 						 const gchar *folder_name,
411 						 const gchar *uid,
412 						 gpointer user_data,
413 						 CamelDBSelectCB callback,
414 						 GError **error);
415 gint		camel_db_count_junk_message_info
416 						(CamelDB *cdb,
417 						 const gchar *table_name,
418 						 guint32 *count,
419 						 GError **error);
420 gint		camel_db_count_unread_message_info
421 						(CamelDB *cdb,
422 						 const gchar *table_name,
423 						 guint32 *count,
424 						 GError **error);
425 gint		camel_db_count_deleted_message_info
426 						(CamelDB *cdb,
427 						 const gchar *table_name,
428 						 guint32 *count,
429 						 GError **error);
430 gint		camel_db_count_total_message_info
431 						(CamelDB *cdb,
432 						 const gchar *table_name,
433 						 guint32 *count,
434 						 GError **error);
435 gint		camel_db_count_visible_message_info
436 						(CamelDB *cdb,
437 						 const gchar *table_name,
438 						 guint32 *count,
439 						 GError **error);
440 gint		camel_db_count_visible_unread_message_info
441 						(CamelDB *cdb,
442 						 const gchar *table_name,
443 						 guint32 *count,
444 						 GError **error);
445 gint		camel_db_count_junk_not_deleted_message_info
446 						(CamelDB *cdb,
447 						 const gchar *table_name,
448 						 guint32 *count,
449 						 GError **error);
450 gint		camel_db_count_message_info	(CamelDB *cdb,
451 						 const gchar *query,
452 						 guint32 *count,
453 						 GError **error);
454 gint		camel_db_get_folder_uids	(CamelDB *cdb,
455 						 const gchar *folder_name,
456 						 const gchar *sort_by,
457 						 const gchar *collate,
458 						 GHashTable *hash,
459 						 GError **error);
460 GPtrArray *	camel_db_get_folder_junk_uids	(CamelDB *cdb,
461 						 const gchar *folder_name,
462 						 GError **error);
463 GPtrArray *	camel_db_get_folder_deleted_uids
464 						(CamelDB *cdb,
465 						 const gchar *folder_name,
466 						 GError **error);
467 gint		camel_db_set_collate		(CamelDB *cdb,
468 						 const gchar *col,
469 						 const gchar *collate,
470 						 CamelDBCollate func);
471 gint		camel_db_start_in_memory_transactions
472 						(CamelDB *cdb,
473 						 GError **error);
474 gint		camel_db_flush_in_memory_transactions
475 						(CamelDB *cdb,
476 						 const gchar *folder_name,
477 						 GError **error);
478 gint		camel_db_reset_folder_version	(CamelDB *cdb,
479 						 const gchar *folder_name,
480 						 gint reset_version,
481 						 GError **error);
482 gboolean	camel_db_maybe_run_maintenance	(CamelDB *cdb,
483 						 GError **error);
484 
485 void		camel_db_release_cache_memory	(void);
486 
487 gchar *		camel_db_sqlize_string		(const gchar *string);
488 void		camel_db_free_sqlized_string	(gchar *string);
489 gchar *		camel_db_get_column_name	(const gchar *raw_name);
490 void		camel_db_camel_mir_free		(CamelMIRecord *record);
491 
492 G_END_DECLS
493 
494 #endif
495