Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(28)

Side by Side Diff: chrome/browser/webdata/web_database_service.cc

Issue 12871006: Second try at splitting WebDataService (minus ownership changes) (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: fix WIN paths Created 7 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
1 // Copyright 2013 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 #include "chrome/browser/webdata/web_database_service.h"
6
7 #include "base/bind.h"
8 #include "base/location.h"
9 #include "chrome/browser/api/webdata/web_data_results.h"
10 #include "chrome/browser/api/webdata/web_data_service_consumer.h"
11 #include "chrome/browser/webdata/web_data_request_manager.h"
12 #include "chrome/browser/webdata/web_data_service.h"
13 // TODO(caitkp): Remove this autofill dependency.
14 #include "components/autofill/browser/autofill_country.h"
15
16 using base::Bind;
17 using base::FilePath;
18 using content::BrowserThread;
19
20
21 ////////////////////////////////////////////////////////////////////////////////
22 //
23 // WebDatabaseServiceInternal implementation.
24 //
25 ////////////////////////////////////////////////////////////////////////////////
26
27 // Refcounted to allow asynchronous destruction on the DB thread.
28 class WebDatabaseServiceInternal
29 : public base::RefCountedThreadSafe<WebDatabaseServiceInternal,
30 BrowserThread::DeleteOnDBThread> {
31 public:
32
dhollowa 2013/03/15 18:56:21 nit: Remove empty line.
Cait (Slow) 2013/03/15 20:43:59 Done.
33 explicit WebDatabaseServiceInternal(const FilePath& path);
34
35 // Initializes the database and notifies caller via callback when complete.
dhollowa 2013/03/15 18:56:21 Please mention that callback is called synchronous
Cait (Slow) 2013/03/15 20:43:59 Done.
36 void InitDatabaseWithCallback(
37 const WebDatabaseService::InitCallback& callback);
38
39 // Opens the database file from the profile path, if an init has not yet been
dhollowa 2013/03/15 18:56:21 Remove comma in "path, if".
Cait (Slow) 2013/03/15 20:43:59 Done.
40 // attempted. Separated from the constructor to ease construction/destruction
41 // of this object on one thread but database access on the DB thread. Returns
42 // the status of the database.
43 sql::InitStatus LoadDatabaseIfNecessary();
44
45 // Shuts down database. |should_reinit| tells us whether or not it should be
46 // possible to re-initialize the DB after the shutdown.
47 void ShutdownDatabase(bool should_reinit);
48
49 // Task wrappers to run database tasks.
50 void DBWriteTaskWrapper(
51 const WebDatabaseService::WriteTask& task,
52 scoped_ptr<WebDataRequest> request);
53 void DBReadTaskWrapper(
54 const WebDatabaseService::ReadTask& task,
55 scoped_ptr<WebDataRequest> request);
56
57 const scoped_refptr<WebDataRequestManager>& request_manager() {
58 return request_manager_; }
dhollowa 2013/03/15 18:56:21 } on new line
Cait (Slow) 2013/03/15 20:43:59 Done.
59
60 WebDatabase* database() {return db_.get();}
dhollowa 2013/03/15 18:56:21 nit: space after { and before }
Cait (Slow) 2013/03/15 20:43:59 Done.
61
62 private:
63 friend struct BrowserThread::DeleteOnThread<BrowserThread::DB>;
64 friend class base::DeleteHelper<WebDatabaseServiceInternal>;
65
66 virtual ~WebDatabaseServiceInternal();
67
68 // Commit the current transaction.
69 void Commit();
70
71 // Path to database file.
72 FilePath db_path_;
73
74 scoped_ptr<WebDatabase> db_;
75
76 // Keeps track of all pending requests made to the db.
77 scoped_refptr<WebDataRequestManager> request_manager_;
78
79 // State of database initialization. Used to prevent the executing of tasks
80 // before the db is ready.
81 sql::InitStatus init_status_;
82
83 // True if an attempt has been made to load the database (even if the attempt
84 // fails), used to avoid continually trying to reinit if the db init fails.
85 bool init_complete_;
86
87 // The application locale. The locale is needed for some database migrations,
88 // and must be read on the UI thread. It's cached here so that we can pass it
89 // to the migration code on the DB thread.
90 const std::string app_locale_;
91
92 DISALLOW_COPY_AND_ASSIGN(WebDatabaseServiceInternal);
93 };
94
95 ////////////////////////////////////////////////////////////////////////////////
96 //
97 // WebDatabaseServiceInternal implementation.
98 //
99 ////////////////////////////////////////////////////////////////////////////////
100
101 WebDatabaseServiceInternal::WebDatabaseServiceInternal(const FilePath& path)
102 : db_path_(path),
103 request_manager_(new WebDataRequestManager()),
104 init_status_(sql::INIT_FAILURE),
105 init_complete_(false),
106 app_locale_(AutofillCountry::ApplicationLocale()) {
107 db_.reset(NULL);
dhollowa 2013/03/15 18:56:21 Not needed.
Cait (Slow) 2013/03/15 20:43:59 Done.
108 }
109
110 void WebDatabaseServiceInternal::InitDatabaseWithCallback(
111 const WebDatabaseService::InitCallback& callback) {
112 if (!callback.is_null()) {
113 callback.Run(LoadDatabaseIfNecessary());
114 }
115 }
116
117 sql::InitStatus WebDatabaseServiceInternal::LoadDatabaseIfNecessary() {
118 if (init_complete_ || db_path_.empty()) {
119 return init_status_;
120 }
121 init_complete_ = true;
122 db_.reset(new WebDatabase());
123 init_status_ = db_->Init(db_path_, app_locale_);
124 if (init_status_ != sql::INIT_OK) {
125 LOG(ERROR) << "Cannot initialize the web database: " << init_status_;
126 db_.reset(NULL);
127 return init_status_;
128 }
129
130 db_->BeginTransaction();
131 return init_status_;
132 }
133
134 void WebDatabaseServiceInternal::ShutdownDatabase(bool should_reinit) {
135 if (db_.get() && init_status_ == sql::INIT_OK)
136 db_->CommitTransaction();
137 db_.reset(NULL);
138 init_complete_ = !should_reinit; // Setting init_complete_ to true will ensure
139 // that the init sequence is not re-run.
140
141 init_status_ = sql::INIT_FAILURE;
142 }
143
144 void WebDatabaseServiceInternal::DBWriteTaskWrapper(
145 const WebDatabaseService::WriteTask& task,
146 scoped_ptr<WebDataRequest> request) {
147 LoadDatabaseIfNecessary();
148 if (db_.get() && init_status_ == sql::INIT_OK && !request->IsCancelled()) {
149 WebDatabase::State state = task.Run(db_.get());
150 if (state == WebDatabase::COMMIT_NEEDED)
151 Commit();
152 }
153 request_manager_->RequestCompleted(request.Pass());
154 }
155
156 void WebDatabaseServiceInternal::DBReadTaskWrapper(
157 const WebDatabaseService::ReadTask& task,
158 scoped_ptr<WebDataRequest> request) {
159 LoadDatabaseIfNecessary();
160 if (db_.get() && init_status_ == sql::INIT_OK && !request->IsCancelled()) {
161 request->SetResult(task.Run(db_.get()).Pass());
162 }
163 request_manager_->RequestCompleted(request.Pass());
164 }
165
166 WebDatabaseServiceInternal::~WebDatabaseServiceInternal() {
167 ShutdownDatabase(false);
168 }
169
170 void WebDatabaseServiceInternal::Commit() {
171 if (db_.get() && init_status_ == sql::INIT_OK) {
172 db_->CommitTransaction();
173 db_->BeginTransaction();
174 } else {
175 NOTREACHED() << "Commit scheduled after Shutdown()";
176 }
177 }
178
179 ////////////////////////////////////////////////////////////////////////////////
180 WebDatabaseService::WebDatabaseService(const base::FilePath& path)
181 : path_(path) {
182 // WebDatabaseService should be instantiated on UI thread.
183 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
184 // WebDatabaseService requires DB thread if instantiated.
185 DCHECK(BrowserThread::IsWellKnownThread(BrowserThread::DB));
186 }
187
188 WebDatabaseService::~WebDatabaseService() {
189 wdbs_internal_ = NULL;
dhollowa 2013/03/15 18:56:21 Not needed.
Cait (Slow) 2013/03/15 20:43:59 Done.
190 }
191
192 void WebDatabaseService::LoadDatabase(const InitCallback& callback) {
193 if (!wdbs_internal_) {
dhollowa 2013/03/15 18:56:21 nit: No need for {}
Cait (Slow) 2013/03/15 20:43:59 Done.
194 wdbs_internal_ = new WebDatabaseServiceInternal(path_);
195 }
196 BrowserThread::PostTask(
197 BrowserThread::DB,
198 FROM_HERE,
199 Bind(&WebDatabaseServiceInternal::InitDatabaseWithCallback,
200 wdbs_internal_, callback));
201 }
202
203 void WebDatabaseService::UnloadDatabase() {
204 if (wdbs_internal_) {
dhollowa 2013/03/15 18:56:21 Please change to the form: if (!wdbs_internal_)
Cait (Slow) 2013/03/15 20:43:59 Done.
205 BrowserThread::PostTask(BrowserThread::DB, FROM_HERE,
206 Bind(&WebDatabaseServiceInternal::ShutdownDatabase,
207 wdbs_internal_, true));
208 }
209 }
210
211 void WebDatabaseService::ShutdownDatabase() {
212 if (wdbs_internal_) {
dhollowa 2013/03/15 18:56:21 Please change to the form: if (!wdbs_internal_)
Cait (Slow) 2013/03/15 20:43:59 Done.
213 BrowserThread::PostTask(BrowserThread::DB, FROM_HERE,
214 Bind(&WebDatabaseServiceInternal::ShutdownDatabase,
215 wdbs_internal_, false));
216 }
217 }
218
219 WebDatabase* WebDatabaseService::GetDatabase() const {
dhollowa 2013/03/15 18:56:21 Consider changing these exceptional methods to *On
Cait (Slow) 2013/03/15 20:43:59 Done. Changed WebDatabaseService method names. Wil
220 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB));
221 if (wdbs_internal_)
dhollowa 2013/03/15 18:56:21 Please change to the form: if (!wdbs_internal_)
Cait (Slow) 2013/03/15 20:43:59 Done.
222 return wdbs_internal_->database();
223 return NULL;
224 }
225
226 void WebDatabaseService::ScheduleDBTask(
227 const tracked_objects::Location& from_here,
228 const WriteTask& task) {
229 if (!wdbs_internal_) {
230 NOTREACHED() << "Task scheduled after Shutdown()";
231 return;
232 }
233
234 scoped_ptr<WebDataRequest> request(
235 new WebDataRequest(NULL, wdbs_internal_->request_manager()));
236
237 BrowserThread::PostTask(BrowserThread::DB, from_here,
238 Bind(&WebDatabaseServiceInternal::DBWriteTaskWrapper, wdbs_internal_,
239 task, base::Passed(&request)));
240 }
241
242 WebDataService::Handle WebDatabaseService::ScheduleDBTaskWithResult(
243 const tracked_objects::Location& from_here,
244 const ReadTask& task,
245 WebDataServiceConsumer* consumer) {
246 DCHECK(consumer);
247 WebDataService::Handle handle = 0;
248
249 if (!wdbs_internal_) {
250 NOTREACHED() << "Task scheduled after Shutdown()";
251 return handle;
252 }
253
254 scoped_ptr<WebDataRequest> request(
255 new WebDataRequest(consumer, wdbs_internal_->request_manager()));
256 handle = request->GetHandle();
257
258 BrowserThread::PostTask(BrowserThread::DB, from_here,
259 Bind(&WebDatabaseServiceInternal::DBReadTaskWrapper, wdbs_internal_,
260 task, base::Passed(&request)));
261
262 return handle;
263 }
264
265 void WebDatabaseService::CancelRequest(WebDataServiceBase::Handle h) {
266 if (wdbs_internal_)
dhollowa 2013/03/15 18:56:21 Please change to the form: if (!wdbs_internal_)
Cait (Slow) 2013/03/15 20:43:59 Done.
267 wdbs_internal_->request_manager()->CancelRequest(h);
268 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698