1 // Copyright (c) 2012 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 "chrome/browser/value_store/value_store_frontend.h"
8 #include "base/debug/trace_event.h"
9 #include "base/files/file_path.h"
10 #include "base/logging.h"
11 #include "chrome/browser/value_store/leveldb_value_store.h"
12 #include "content/public/browser/browser_thread.h"
14 using content::BrowserThread
;
16 class ValueStoreFrontend::Backend
: public base::RefCountedThreadSafe
<Backend
> {
18 Backend() : storage_(NULL
) {}
20 void Init(const base::FilePath
& db_path
) {
21 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
23 TRACE_EVENT0("ValueStoreFrontend::Backend", "Init");
25 storage_
= new LeveldbValueStore(db_path
);
28 // This variant is useful for testing (using a mock ValueStore).
29 void InitWithStore(scoped_ptr
<ValueStore
> storage
) {
30 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
32 storage_
= storage
.release();
35 void Get(const std::string
& key
,
36 const ValueStoreFrontend::ReadCallback
& callback
) {
37 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
38 ValueStore::ReadResult result
= storage_
->Get(key
);
40 // Extract the value from the ReadResult and pass ownership of it to the
42 scoped_ptr
<base::Value
> value
;
43 if (!result
->HasError()) {
44 result
->settings().RemoveWithoutPathExpansion(key
, &value
);
46 LOG(WARNING
) << "Reading " << key
<< " from " << db_path_
.value()
47 << " failed: " << result
->error().message
;
50 BrowserThread::PostTask(BrowserThread::UI
, FROM_HERE
,
51 base::Bind(&ValueStoreFrontend::Backend::RunCallback
,
52 this, callback
, base::Passed(&value
)));
55 void Set(const std::string
& key
, scoped_ptr
<base::Value
> value
) {
56 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
57 // We don't need the old value, so skip generating changes.
58 storage_
->Set(ValueStore::IGNORE_QUOTA
| ValueStore::NO_GENERATE_CHANGES
,
62 void Remove(const std::string
& key
) {
63 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
64 storage_
->Remove(key
);
68 friend class base::RefCountedThreadSafe
<Backend
>;
71 if (BrowserThread::CurrentlyOn(BrowserThread::FILE)) {
74 BrowserThread::DeleteSoon(BrowserThread::FILE, FROM_HERE
, storage_
);
78 void RunCallback(const ValueStoreFrontend::ReadCallback
& callback
,
79 scoped_ptr
<base::Value
> value
) {
80 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
81 callback
.Run(value
.Pass());
84 // The actual ValueStore that handles persisting the data to disk. Used
85 // exclusively on the FILE thread.
88 base::FilePath db_path_
;
90 DISALLOW_COPY_AND_ASSIGN(Backend
);
93 ValueStoreFrontend::ValueStoreFrontend()
94 : backend_(new Backend()) {
97 ValueStoreFrontend::ValueStoreFrontend(const base::FilePath
& db_path
)
98 : backend_(new Backend()) {
102 ValueStoreFrontend::ValueStoreFrontend(scoped_ptr
<ValueStore
> value_store
)
103 : backend_(new Backend()) {
104 BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE
,
105 base::Bind(&ValueStoreFrontend::Backend::InitWithStore
,
106 backend_
, base::Passed(&value_store
)));
109 ValueStoreFrontend::~ValueStoreFrontend() {
110 DCHECK(CalledOnValidThread());
113 void ValueStoreFrontend::Init(const base::FilePath
& db_path
) {
114 BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE
,
115 base::Bind(&ValueStoreFrontend::Backend::Init
,
119 void ValueStoreFrontend::Get(const std::string
& key
,
120 const ReadCallback
& callback
) {
121 DCHECK(CalledOnValidThread());
123 BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE
,
124 base::Bind(&ValueStoreFrontend::Backend::Get
,
125 backend_
, key
, callback
));
128 void ValueStoreFrontend::Set(const std::string
& key
,
129 scoped_ptr
<base::Value
> value
) {
130 DCHECK(CalledOnValidThread());
132 BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE
,
133 base::Bind(&ValueStoreFrontend::Backend::Set
,
134 backend_
, key
, base::Passed(&value
)));
137 void ValueStoreFrontend::Remove(const std::string
& key
) {
138 DCHECK(CalledOnValidThread());
140 BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE
,
141 base::Bind(&ValueStoreFrontend::Backend::Remove
,