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

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: Missed a couple 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 explicit WebDatabaseServiceInternal(const FilePath& path);
33
34 // Initializes the database and notifies caller via callback when complete.
35 // Callback is called synchronously.
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
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_;
59 }
60
61 WebDatabase* database() { return db_.get(); }
62
63 private:
64 friend struct BrowserThread::DeleteOnThread<BrowserThread::DB>;
65 friend class base::DeleteHelper<WebDatabaseServiceInternal>;
66
67 virtual ~WebDatabaseServiceInternal();
68
69 // Commit the current transaction.
70 void Commit();
71
72 // Path to database file.
73 FilePath db_path_;
74
75 scoped_ptr<WebDatabase> db_;
76
77 // Keeps track of all pending requests made to the db.
78 scoped_refptr<WebDataRequestManager> request_manager_;
79
80 // State of database initialization. Used to prevent the executing of tasks
81 // before the db is ready.
82 sql::InitStatus init_status_;
83
84 // True if an attempt has been made to load the database (even if the attempt
85 // fails), used to avoid continually trying to reinit if the db init fails.
86 bool init_complete_;
87
88 // The application locale. The locale is needed for some database migrations,
89 // and must be read on the UI thread. It's cached here so that we can pass it
90 // to the migration code on the DB thread.
91 const std::string app_locale_;
92
93 DISALLOW_COPY_AND_ASSIGN(WebDatabaseServiceInternal);
94 };
95
96 ////////////////////////////////////////////////////////////////////////////////
97 //
98 // WebDatabaseServiceInternal implementation.
99 //
100 ////////////////////////////////////////////////////////////////////////////////
101
102 WebDatabaseServiceInternal::WebDatabaseServiceInternal(const FilePath& path)
103 : db_path_(path),
104 request_manager_(new WebDataRequestManager()),
105 init_status_(sql::INIT_FAILURE),
106 init_complete_(false),
107 app_locale_(AutofillCountry::ApplicationLocale()) {
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)
dhollowa 2013/03/15 23:50:31 if(db_ &&...
Cait (Slow) 2013/03/16 21:34:22 Done.
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()) {
dhollowa 2013/03/15 23:50:31 if(db_ &&...
Cait (Slow) 2013/03/16 21:34:22 Done.
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()) {
dhollowa 2013/03/15 23:50:31 if(db_ &&...
Cait (Slow) 2013/03/16 21:34:22 Done.
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) {
dhollowa 2013/03/15 23:50:31 if(db_ &&...
Cait (Slow) 2013/03/16 21:34:22 Done.
172 db_->CommitTransaction();
dhollowa 2013/03/15 23:50:31 nit: Indent
Cait (Slow) 2013/03/16 21:34:22 Done.
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 }
190
191 void WebDatabaseService::LoadDatabase(const InitCallback& callback) {
192 if (!wdbs_internal_)
193 wdbs_internal_ = new WebDatabaseServiceInternal(path_);
194
195 BrowserThread::PostTask(
196 BrowserThread::DB,
197 FROM_HERE,
198 Bind(&WebDatabaseServiceInternal::InitDatabaseWithCallback,
199 wdbs_internal_, callback));
200 }
201
202 void WebDatabaseService::UnloadDatabase() {
203 if (!wdbs_internal_)
204 return;
205 BrowserThread::PostTask(BrowserThread::DB, FROM_HERE,
206 Bind(&WebDatabaseServiceInternal::ShutdownDatabase,
207 wdbs_internal_, true));
208 }
209
210 void WebDatabaseService::ShutdownDatabase() {
211 if (!wdbs_internal_)
212 return;
213 BrowserThread::PostTask(BrowserThread::DB, FROM_HERE,
214 Bind(&WebDatabaseServiceInternal::ShutdownDatabase,
215 wdbs_internal_, false));
216 }
217
218 WebDatabase* WebDatabaseService::GetDatabaseOnDB() const {
219 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB));
220 if (!wdbs_internal_)
221 return NULL;
222 return wdbs_internal_->database();
223 }
224
225 void WebDatabaseService::ScheduleDBTask(
226 const tracked_objects::Location& from_here,
dhollowa 2013/03/15 23:50:31 nit: Indent
Cait (Slow) 2013/03/16 21:34:22 Done.
227 const WriteTask& task) {
228 if (!wdbs_internal_) {
229 NOTREACHED() << "Task scheduled after Shutdown()";
230 return;
231 }
232
233 scoped_ptr<WebDataRequest> request(
234 new WebDataRequest(NULL, wdbs_internal_->request_manager()));
235
236 BrowserThread::PostTask(BrowserThread::DB, from_here,
237 Bind(&WebDatabaseServiceInternal::DBWriteTaskWrapper, wdbs_internal_,
238 task, base::Passed(&request)));
239 }
240
241 WebDataService::Handle WebDatabaseService::ScheduleDBTaskWithResult(
242 const tracked_objects::Location& from_here,
dhollowa 2013/03/15 23:50:31 nit: Indent
Cait (Slow) 2013/03/16 21:34:22 Done.
243 const ReadTask& task,
244 WebDataServiceConsumer* consumer) {
245 DCHECK(consumer);
246 WebDataService::Handle handle = 0;
247
248 if (!wdbs_internal_) {
249 NOTREACHED() << "Task scheduled after Shutdown()";
250 return handle;
251 }
252
253 scoped_ptr<WebDataRequest> request(
254 new WebDataRequest(consumer, wdbs_internal_->request_manager()));
255 handle = request->GetHandle();
256
257 BrowserThread::PostTask(BrowserThread::DB, from_here,
258 Bind(&WebDatabaseServiceInternal::DBReadTaskWrapper, wdbs_internal_,
259 task, base::Passed(&request)));
260
261 return handle;
262 }
263
264 void WebDatabaseService::CancelRequest(WebDataServiceBase::Handle h) {
265 if (!wdbs_internal_)
266 return;
267 wdbs_internal_->request_manager()->CancelRequest(h);
268 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698