OLD | NEW |
| (Empty) |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | |
2 // Use of this source code is governed by a BSD-style license that can be | |
3 // found in the LICENSE file. | |
4 | |
5 #ifndef SYNC_API_ATTACHMENTS_ATTACHMENT_STORE_H_ | |
6 #define SYNC_API_ATTACHMENTS_ATTACHMENT_STORE_H_ | |
7 | |
8 #include <memory> | |
9 | |
10 #include "base/callback.h" | |
11 #include "base/macros.h" | |
12 #include "base/memory/ref_counted.h" | |
13 #include "sync/api/attachments/attachment.h" | |
14 #include "sync/api/attachments/attachment_id.h" | |
15 #include "sync/api/attachments/attachment_metadata.h" | |
16 #include "sync/base/sync_export.h" | |
17 | |
18 namespace base { | |
19 class FilePath; | |
20 class SequencedTaskRunner; | |
21 } // namespace base | |
22 | |
23 namespace syncer { | |
24 | |
25 class AttachmentStoreBackend; | |
26 class AttachmentStoreForSync; | |
27 class AttachmentStoreFrontend; | |
28 | |
29 // AttachmentStore is a place to locally store and access Attachments. | |
30 // | |
31 // AttachmentStore class is an interface exposed to data type and | |
32 // AttachmentService code. | |
33 // It also contains factory methods for default attachment store | |
34 // implementations. | |
35 // Destroying this object does not necessarily cancel outstanding async | |
36 // operations. If you need cancel like semantics, use WeakPtr in the callbacks. | |
37 class SYNC_EXPORT AttachmentStore { | |
38 public: | |
39 // TODO(maniscalco): Consider udpating Read and Write methods to support | |
40 // resumable transfers (bug 353292). | |
41 | |
42 // The result status of an attachment store operation. | |
43 // Do not re-order or delete these entries; they are used in a UMA histogram. | |
44 enum Result { | |
45 SUCCESS = 0, // No error, all completed successfully. | |
46 UNSPECIFIED_ERROR = 1, // An unspecified error occurred for >= 1 item. | |
47 STORE_INITIALIZATION_FAILED = 2, // AttachmentStore initialization failed. | |
48 // When adding a value here, you must increment RESULT_SIZE below. | |
49 }; | |
50 static const int RESULT_SIZE = | |
51 10; // Size of the Result enum; used for histograms. | |
52 | |
53 // Each attachment can have references from sync or model type. Tracking these | |
54 // references is needed for lifetime management of attachment, it can only be | |
55 // deleted from the store when it doesn't have references. | |
56 enum Component { | |
57 MODEL_TYPE, | |
58 SYNC, | |
59 }; | |
60 | |
61 typedef base::Callback<void(const Result&)> InitCallback; | |
62 typedef base::Callback<void(const Result&, | |
63 std::unique_ptr<AttachmentMap>, | |
64 std::unique_ptr<AttachmentIdList>)> | |
65 ReadCallback; | |
66 typedef base::Callback<void(const Result&)> WriteCallback; | |
67 typedef base::Callback<void(const Result&)> DropCallback; | |
68 typedef base::Callback<void(const Result&, | |
69 std::unique_ptr<AttachmentMetadataList>)> | |
70 ReadMetadataCallback; | |
71 | |
72 ~AttachmentStore(); | |
73 | |
74 // Asynchronously reads the attachments identified by |ids|. | |
75 // | |
76 // |callback| will be invoked when finished. AttachmentStore will attempt to | |
77 // read all attachments specified in ids. If any of the attachments do not | |
78 // exist or could not be read, |callback|'s Result will be UNSPECIFIED_ERROR. | |
79 // Callback's AttachmentMap will contain all attachments that were | |
80 // successfully read, AttachmentIdList will contain attachment ids of | |
81 // attachments that are unavailable in attachment store, these need to be | |
82 // downloaded from server. | |
83 // | |
84 // Reads on individual attachments are treated atomically; |callback| will not | |
85 // read only part of an attachment. | |
86 void Read(const AttachmentIdList& ids, const ReadCallback& callback); | |
87 | |
88 // Asynchronously writes |attachments| to the store. | |
89 // | |
90 // Will not overwrite stored attachments. Attempting to overwrite an | |
91 // attachment that already exists is not an error. | |
92 // | |
93 // |callback| will be invoked when finished. If any of the attachments could | |
94 // not be written |callback|'s Result will be UNSPECIFIED_ERROR. When this | |
95 // happens, some or none of the attachments may have been written | |
96 // successfully. | |
97 void Write(const AttachmentList& attachments, const WriteCallback& callback); | |
98 | |
99 // Asynchronously drops |attchments| from this store. | |
100 // | |
101 // This does not remove attachments from the server. | |
102 // | |
103 // |callback| will be invoked when finished. Attempting to drop an attachment | |
104 // that does not exist is not an error. If any of the existing attachment | |
105 // could not be dropped, |callback|'s Result will be UNSPECIFIED_ERROR. When | |
106 // this happens, some or none of the attachments may have been dropped | |
107 // successfully. | |
108 void Drop(const AttachmentIdList& ids, const DropCallback& callback); | |
109 | |
110 // Asynchronously reads metadata for the attachments identified by |ids|. | |
111 // | |
112 // |callback| will be invoked when finished. AttachmentStore will attempt to | |
113 // read metadata for all attachments specified in ids. If any of the | |
114 // metadata entries do not exist or could not be read, |callback|'s Result | |
115 // will be UNSPECIFIED_ERROR. | |
116 void ReadMetadataById(const AttachmentIdList& ids, | |
117 const ReadMetadataCallback& callback); | |
118 | |
119 // Asynchronously reads metadata for all attachments with |component_| | |
120 // reference in the store. | |
121 // | |
122 // |callback| will be invoked when finished. If any of the metadata entries | |
123 // could not be read, |callback|'s Result will be UNSPECIFIED_ERROR. | |
124 void ReadMetadata(const ReadMetadataCallback& callback); | |
125 | |
126 // Given current AttachmentStore (this) creates separate AttachmentStore that | |
127 // will be used by sync components (AttachmentService). Resulting | |
128 // AttachmentStore is backed by the same frontend/backend. | |
129 std::unique_ptr<AttachmentStoreForSync> CreateAttachmentStoreForSync() const; | |
130 | |
131 // Creates an AttachmentStore backed by in-memory implementation of attachment | |
132 // store. For now frontend lives on the same thread as backend. | |
133 static std::unique_ptr<AttachmentStore> CreateInMemoryStore(); | |
134 | |
135 // Creates an AttachmentStore backed by on-disk implementation of attachment | |
136 // store. Opens corresponding leveldb database located at |path|. All backend | |
137 // operations are scheduled to |backend_task_runner|. Opening attachment store | |
138 // is asynchronous, once it finishes |callback| will be called on the thread | |
139 // that called CreateOnDiskStore. Calling Read/Write/Drop before | |
140 // initialization completed is allowed. Later if initialization fails these | |
141 // operations will fail with STORE_INITIALIZATION_FAILED error. | |
142 static std::unique_ptr<AttachmentStore> CreateOnDiskStore( | |
143 const base::FilePath& path, | |
144 const scoped_refptr<base::SequencedTaskRunner>& backend_task_runner, | |
145 const InitCallback& callback); | |
146 | |
147 // Creates set of AttachmentStore/AttachmentStoreFrontend instances for tests | |
148 // that provide their own implementation of AttachmentstoreBackend for | |
149 // mocking. | |
150 static std::unique_ptr<AttachmentStore> CreateMockStoreForTest( | |
151 std::unique_ptr<AttachmentStoreBackend> backend); | |
152 | |
153 protected: | |
154 AttachmentStore(const scoped_refptr<AttachmentStoreFrontend>& frontend, | |
155 Component component); | |
156 | |
157 const scoped_refptr<AttachmentStoreFrontend>& frontend() { return frontend_; } | |
158 Component component() const { return component_; } | |
159 | |
160 private: | |
161 scoped_refptr<AttachmentStoreFrontend> frontend_; | |
162 // Modification operations with attachment store will be performed on behalf | |
163 // of |component_|. | |
164 const Component component_; | |
165 | |
166 DISALLOW_COPY_AND_ASSIGN(AttachmentStore); | |
167 }; | |
168 | |
169 // AttachmentStoreForSync extends AttachmentStore and provides additional | |
170 // functions necessary for AttachmentService. These are needed when | |
171 // AttachmentService writes attachment on behalf of model type after download | |
172 // and takes reference on attachment for the duration of upload. | |
173 // Model type implementation shouldn't use this interface. | |
174 class SYNC_EXPORT AttachmentStoreForSync : public AttachmentStore { | |
175 public: | |
176 ~AttachmentStoreForSync(); | |
177 | |
178 // Asynchronously adds reference from sync to attachments. | |
179 void SetSyncReference(const AttachmentIdList& ids); | |
180 | |
181 // Asynchronously adds reference from model type to attachments. | |
182 // Needed in GetOrDownloadAttachments when attachment is in local store but | |
183 // doesn't have model type reference. | |
184 void SetModelTypeReference(const AttachmentIdList& ids); | |
185 | |
186 // Asynchronously drops sync reference from attachments. | |
187 void DropSyncReference(const AttachmentIdList& ids); | |
188 | |
189 // Asynchronously reads metadata for all attachments with |sync_component_| | |
190 // reference in the store. | |
191 // | |
192 // |callback| will be invoked when finished. If any of the metadata entries | |
193 // could not be read, |callback|'s Result will be UNSPECIFIED_ERROR. | |
194 void ReadMetadataForSync(const ReadMetadataCallback& callback); | |
195 | |
196 private: | |
197 friend class AttachmentStore; | |
198 AttachmentStoreForSync(const scoped_refptr<AttachmentStoreFrontend>& frontend, | |
199 Component consumer_component, | |
200 Component sync_component); | |
201 | |
202 // |sync_component_| is passed to frontend when sync related operations are | |
203 // perfromed. | |
204 const Component sync_component_; | |
205 | |
206 DISALLOW_COPY_AND_ASSIGN(AttachmentStoreForSync); | |
207 }; | |
208 | |
209 } // namespace syncer | |
210 | |
211 #endif // SYNC_API_ATTACHMENTS_ATTACHMENT_STORE_H_ | |
OLD | NEW |