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.
5 #include "components/webdata/common/web_database_service.h"
8 #include "base/location.h"
9 #include "components/webdata/common/web_data_request_manager.h"
10 #include "components/webdata/common/web_data_results.h"
11 #include "components/webdata/common/web_data_service_backend.h"
12 #include "components/webdata/common/web_data_service_consumer.h"
17 // Receives messages from the backend on the DB thread, posts them to
18 // WebDatabaseService on the UI thread.
19 class WebDatabaseService::BackendDelegate :
20 public WebDataServiceBackend::Delegate {
23 const base::WeakPtr<WebDatabaseService>& web_database_service)
24 : web_database_service_(web_database_service),
25 callback_thread_(base::MessageLoopProxy::current()) {
28 virtual void DBLoaded(sql::InitStatus status) OVERRIDE {
29 callback_thread_->PostTask(
31 base::Bind(&WebDatabaseService::OnDatabaseLoadDone,
32 web_database_service_,
36 const base::WeakPtr<WebDatabaseService> web_database_service_;
37 scoped_refptr<base::MessageLoopProxy> callback_thread_;
40 WebDatabaseService::WebDatabaseService(
41 const base::FilePath& path,
42 const scoped_refptr<base::MessageLoopProxy>& ui_thread,
43 const scoped_refptr<base::MessageLoopProxy>& db_thread)
44 : base::RefCountedDeleteOnMessageLoop<WebDatabaseService>(ui_thread),
46 weak_ptr_factory_(this),
48 db_thread_(db_thread) {
49 // WebDatabaseService should be instantiated on UI thread.
50 DCHECK(ui_thread->BelongsToCurrentThread());
51 // WebDatabaseService requires DB thread if instantiated.
52 DCHECK(db_thread.get());
55 WebDatabaseService::~WebDatabaseService() {
58 void WebDatabaseService::AddTable(scoped_ptr<WebDatabaseTable> table) {
59 if (!wds_backend_.get()) {
60 wds_backend_ = new WebDataServiceBackend(
61 path_, new BackendDelegate(weak_ptr_factory_.GetWeakPtr()),
64 wds_backend_->AddTable(table.Pass());
67 void WebDatabaseService::LoadDatabase() {
68 DCHECK(wds_backend_.get());
72 Bind(&WebDataServiceBackend::InitDatabase, wds_backend_));
75 void WebDatabaseService::UnloadDatabase() {
77 if (!wds_backend_.get())
79 db_thread_->PostTask(FROM_HERE,
80 Bind(&WebDataServiceBackend::ShutdownDatabase,
84 void WebDatabaseService::ShutdownDatabase() {
86 weak_ptr_factory_.InvalidateWeakPtrs();
87 loaded_callbacks_.clear();
88 error_callbacks_.clear();
89 if (!wds_backend_.get())
91 db_thread_->PostTask(FROM_HERE,
92 Bind(&WebDataServiceBackend::ShutdownDatabase,
93 wds_backend_, false));
96 WebDatabase* WebDatabaseService::GetDatabaseOnDB() const {
97 DCHECK(db_thread_->BelongsToCurrentThread());
98 if (!wds_backend_.get())
100 return wds_backend_->database();
103 scoped_refptr<WebDataServiceBackend> WebDatabaseService::GetBackend() const {
107 void WebDatabaseService::ScheduleDBTask(
108 const tracked_objects::Location& from_here,
109 const WriteTask& task) {
110 if (!wds_backend_.get()) {
111 NOTREACHED() << "Task scheduled after Shutdown()";
115 scoped_ptr<WebDataRequest> request(
116 new WebDataRequest(NULL, wds_backend_->request_manager().get()));
118 db_thread_->PostTask(from_here,
119 Bind(&WebDataServiceBackend::DBWriteTaskWrapper, wds_backend_,
120 task, base::Passed(&request)));
123 WebDataServiceBase::Handle WebDatabaseService::ScheduleDBTaskWithResult(
124 const tracked_objects::Location& from_here,
125 const ReadTask& task,
126 WebDataServiceConsumer* consumer) {
128 WebDataServiceBase::Handle handle = 0;
130 if (!wds_backend_.get()) {
131 NOTREACHED() << "Task scheduled after Shutdown()";
135 scoped_ptr<WebDataRequest> request(
136 new WebDataRequest(consumer, wds_backend_->request_manager().get()));
137 handle = request->GetHandle();
139 db_thread_->PostTask(from_here,
140 Bind(&WebDataServiceBackend::DBReadTaskWrapper, wds_backend_,
141 task, base::Passed(&request)));
146 void WebDatabaseService::CancelRequest(WebDataServiceBase::Handle h) {
147 if (!wds_backend_.get())
149 wds_backend_->request_manager()->CancelRequest(h);
152 void WebDatabaseService::RegisterDBLoadedCallback(
153 const DBLoadedCallback& callback) {
154 loaded_callbacks_.push_back(callback);
157 void WebDatabaseService::RegisterDBErrorCallback(
158 const DBLoadErrorCallback& callback) {
159 error_callbacks_.push_back(callback);
162 void WebDatabaseService::OnDatabaseLoadDone(sql::InitStatus status) {
163 if (status == sql::INIT_OK) {
166 for (size_t i = 0; i < loaded_callbacks_.size(); i++) {
167 if (!loaded_callbacks_[i].is_null())
168 loaded_callbacks_[i].Run();
171 loaded_callbacks_.clear();
173 // Notify that the database load failed.
174 for (size_t i = 0; i < error_callbacks_.size(); i++) {
175 if (!error_callbacks_[i].is_null())
176 error_callbacks_[i].Run(status);
179 error_callbacks_.clear();