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 "base/thread_task_runner_handle.h"
10 #include "components/webdata/common/web_data_request_manager.h"
11 #include "components/webdata/common/web_data_results.h"
12 #include "components/webdata/common/web_data_service_consumer.h"
13 #include "components/webdata/common/web_database_backend.h"
18 // Receives messages from the backend on the DB thread, posts them to
19 // WebDatabaseService on the UI thread.
20 class WebDatabaseService::BackendDelegate
21 : public WebDatabaseBackend::Delegate
{
23 BackendDelegate(const base::WeakPtr
<WebDatabaseService
>& web_database_service
)
24 : web_database_service_(web_database_service
),
25 callback_thread_(base::ThreadTaskRunnerHandle::Get()) {}
27 void DBLoaded(sql::InitStatus status
) override
{
28 callback_thread_
->PostTask(
30 base::Bind(&WebDatabaseService::OnDatabaseLoadDone
,
31 web_database_service_
,
35 const base::WeakPtr
<WebDatabaseService
> web_database_service_
;
36 scoped_refptr
<base::SingleThreadTaskRunner
> callback_thread_
;
39 WebDatabaseService::WebDatabaseService(
40 const base::FilePath
& path
,
41 scoped_refptr
<base::SingleThreadTaskRunner
> ui_thread
,
42 scoped_refptr
<base::SingleThreadTaskRunner
> db_thread
)
43 : base::RefCountedDeleteOnMessageLoop
<WebDatabaseService
>(ui_thread
),
46 db_thread_(db_thread
),
47 weak_ptr_factory_(this) {
48 // WebDatabaseService should be instantiated on UI thread.
49 DCHECK(ui_thread
->BelongsToCurrentThread());
50 // WebDatabaseService requires DB thread if instantiated.
51 DCHECK(db_thread
.get());
54 WebDatabaseService::~WebDatabaseService() {
57 void WebDatabaseService::AddTable(scoped_ptr
<WebDatabaseTable
> table
) {
58 if (!web_db_backend_
.get()) {
59 web_db_backend_
= new WebDatabaseBackend(
60 path_
, new BackendDelegate(weak_ptr_factory_
.GetWeakPtr()), db_thread_
);
62 web_db_backend_
->AddTable(table
.Pass());
65 void WebDatabaseService::LoadDatabase() {
66 DCHECK(web_db_backend_
.get());
68 FROM_HERE
, Bind(&WebDatabaseBackend::InitDatabase
, web_db_backend_
));
71 void WebDatabaseService::ShutdownDatabase() {
73 loaded_callbacks_
.clear();
74 error_callbacks_
.clear();
75 weak_ptr_factory_
.InvalidateWeakPtrs();
76 if (!web_db_backend_
.get())
79 FROM_HERE
, Bind(&WebDatabaseBackend::ShutdownDatabase
, web_db_backend_
));
82 WebDatabase
* WebDatabaseService::GetDatabaseOnDB() const {
83 DCHECK(db_thread_
->BelongsToCurrentThread());
84 return web_db_backend_
.get() ? web_db_backend_
->database() : NULL
;
87 scoped_refptr
<WebDatabaseBackend
> WebDatabaseService::GetBackend() const {
88 return web_db_backend_
;
91 void WebDatabaseService::ScheduleDBTask(
92 const tracked_objects::Location
& from_here
,
93 const WriteTask
& task
) {
94 DCHECK(web_db_backend_
.get());
95 scoped_ptr
<WebDataRequest
> request(
96 new WebDataRequest(NULL
, web_db_backend_
->request_manager().get()));
98 from_here
, Bind(&WebDatabaseBackend::DBWriteTaskWrapper
, web_db_backend_
,
99 task
, base::Passed(&request
)));
102 WebDataServiceBase::Handle
WebDatabaseService::ScheduleDBTaskWithResult(
103 const tracked_objects::Location
& from_here
,
104 const ReadTask
& task
,
105 WebDataServiceConsumer
* consumer
) {
107 DCHECK(web_db_backend_
.get());
108 scoped_ptr
<WebDataRequest
> request(
109 new WebDataRequest(consumer
, web_db_backend_
->request_manager().get()));
110 WebDataServiceBase::Handle handle
= request
->GetHandle();
111 db_thread_
->PostTask(
112 from_here
, Bind(&WebDatabaseBackend::DBReadTaskWrapper
, web_db_backend_
,
113 task
, base::Passed(&request
)));
117 void WebDatabaseService::CancelRequest(WebDataServiceBase::Handle h
) {
118 if (!web_db_backend_
.get())
120 web_db_backend_
->request_manager()->CancelRequest(h
);
123 void WebDatabaseService::RegisterDBLoadedCallback(
124 const DBLoadedCallback
& callback
) {
125 loaded_callbacks_
.push_back(callback
);
128 void WebDatabaseService::RegisterDBErrorCallback(
129 const DBLoadErrorCallback
& callback
) {
130 error_callbacks_
.push_back(callback
);
133 void WebDatabaseService::OnDatabaseLoadDone(sql::InitStatus status
) {
134 if (status
== sql::INIT_OK
) {
137 for (size_t i
= 0; i
< loaded_callbacks_
.size(); i
++) {
138 if (!loaded_callbacks_
[i
].is_null())
139 loaded_callbacks_
[i
].Run();
142 loaded_callbacks_
.clear();
144 // Notify that the database load failed.
145 for (size_t i
= 0; i
< error_callbacks_
.size(); i
++) {
146 if (!error_callbacks_
[i
].is_null())
147 error_callbacks_
[i
].Run(status
);
150 error_callbacks_
.clear();