comparison src/lib-index/mail-index-transaction-view.c @ 2224:a816e2d88406 HEAD

Added mail_index_transaction_get_updated_view() which can be used to access uncommitted messages.
author Timo Sirainen <tss@iki.fi>
date Tue, 22 Jun 2004 10:36:33 +0300
parents
children 51719889ffcf
comparison
equal deleted inserted replaced
2223:cf5967239463 2224:a816e2d88406
1 /* Copyright (C) 2004 Timo Sirainen */
2
3 #include "lib.h"
4 #include "buffer.h"
5 #include "mail-index-private.h"
6 #include "mail-index-view-private.h"
7 #include "mail-index-transaction-private.h"
8
9 struct mail_index_view_transaction {
10 struct mail_index_view view;
11 struct mail_index_view_methods *parent;
12 struct mail_index_transaction *t;
13 };
14
15 static void _tview_close(struct mail_index_view *view)
16 {
17 struct mail_index_view_transaction *tview =
18 (struct mail_index_view_transaction *)view;
19
20 tview->t->updated_view = NULL;
21
22 return tview->parent->close(view);
23 }
24
25 static uint32_t _tview_get_message_count(struct mail_index_view *view)
26 {
27 struct mail_index_view_transaction *tview =
28 (struct mail_index_view_transaction *)view;
29
30 return view->messages_count +
31 (tview->t->last_new_seq == 0 ? 0 :
32 tview->t->last_new_seq - tview->t->first_new_seq);
33 }
34
35 static int _tview_get_header(struct mail_index_view *view,
36 const struct mail_index_header **hdr_r)
37 {
38 struct mail_index_view_transaction *tview =
39 (struct mail_index_view_transaction *)view;
40
41 if (tview->parent->get_header(view, hdr_r) < 0)
42 return -1;
43
44 if ((*hdr_r)->messages_count != view->messages_count) {
45 /* messages_count differs, use a modified copy.
46 FIXME: same problems as with _view_get_header().. */
47 view->tmp_hdr_copy = **hdr_r;
48 view->tmp_hdr_copy.messages_count = view->messages_count;
49 *hdr_r = &view->tmp_hdr_copy;
50 }
51 return 0;
52 }
53
54 static int _tview_lookup_full(struct mail_index_view *view, uint32_t seq,
55 struct mail_index_map **map_r,
56 const struct mail_index_record **rec_r)
57 {
58 struct mail_index_view_transaction *tview =
59 (struct mail_index_view_transaction *)view;
60
61 if (seq >= tview->t->first_new_seq) {
62 /* FIXME: is this right to return index map..?
63 it's not there yet. */
64 *map_r = view->index->map;
65 *rec_r = mail_index_transaction_lookup(tview->t, seq);
66 return 1;
67 } else {
68 return tview->parent->lookup_full(view, seq, map_r, rec_r);
69 }
70 }
71
72 static int _tview_lookup_uid(struct mail_index_view *view, uint32_t seq,
73 uint32_t *uid_r)
74 {
75 struct mail_index_view_transaction *tview =
76 (struct mail_index_view_transaction *)view;
77
78 if (seq >= tview->t->first_new_seq) {
79 *uid_r = mail_index_transaction_lookup(tview->t, seq)->uid;
80 return 0;
81 } else {
82 return tview->parent->lookup_uid(view, seq, uid_r);
83 }
84 }
85
86 static int _tview_lookup_uid_range(struct mail_index_view *view,
87 uint32_t first_uid, uint32_t last_uid,
88 uint32_t *first_seq_r, uint32_t *last_seq_r)
89 {
90 struct mail_index_view_transaction *tview =
91 (struct mail_index_view_transaction *)view;
92
93 if (tview->parent->lookup_uid_range(view, first_uid, last_uid,
94 first_seq_r, last_seq_r) < 0)
95 return -1;
96
97 /* FIXME: we don't need this function yet.. new UIDs might be 0 as
98 well.. */
99
100 if (*first_seq_r == 0) {
101 /* nothing found, either doesn't exist or it's completely
102 newly appended. */
103 } else if (*last_seq_r + 1 == tview->t->first_new_seq) {
104 /* last_seq_r may be growed from transactions */
105 }
106
107 return 0;
108 }
109
110 static int _tview_lookup_first(struct mail_index_view *view,
111 enum mail_flags flags, uint8_t flags_mask,
112 uint32_t *seq_r)
113 {
114 struct mail_index_view_transaction *tview =
115 (struct mail_index_view_transaction *)view;
116 const struct mail_index_record *rec;
117 uint32_t seq, message_count;
118
119 if (tview->parent->lookup_first(view, flags, flags_mask, seq_r) < 0)
120 return -1;
121
122 if (*seq_r != 0)
123 return 0;
124
125 rec = buffer_get_data(tview->t->appends, NULL);
126 seq = tview->t->first_new_seq;
127 message_count = tview->t->last_new_seq;
128 for (; seq <= message_count; seq++) {
129 if ((rec->flags & flags_mask) == (uint8_t)flags) {
130 *seq_r = seq;
131 break;
132 }
133 rec = CONST_PTR_OFFSET(rec, view->index->record_size);
134 }
135
136 return 0;
137 }
138
139 static struct mail_index_view_methods view_methods = {
140 _tview_close,
141 _tview_get_message_count,
142 _tview_get_header,
143 _tview_lookup_full,
144 _tview_lookup_uid,
145 _tview_lookup_uid_range,
146 _tview_lookup_first
147 };
148
149 struct mail_index_view *
150 mail_index_transaction_get_updated_view(struct mail_index_transaction *t)
151 {
152 struct mail_index_view_transaction *tview;
153
154 if (t->updated_view == NULL) {
155 tview = i_new(struct mail_index_view_transaction, 1);
156 mail_index_view_clone(&tview->view, t->view);
157 tview->view.methods = view_methods;
158 tview->parent = &t->view->methods;
159 tview->t = t;
160
161 t->updated_view = &tview->view;
162 }
163
164 return t->updated_view;
165 }