blob: b98206322dafd58120ef542da053e2c3d0e2efbc [file] [log] [blame]
// Copyright 2016 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef COMPONENTS_SERVICES_LEVELDB_LEVELDB_DATABASE_IMPL_H_
#define COMPONENTS_SERVICES_LEVELDB_LEVELDB_DATABASE_IMPL_H_
#include <memory>
#include <tuple>
#include <vector>
#include "base/memory/scoped_refptr.h"
#include "base/sequenced_task_runner.h"
#include "base/threading/sequence_bound.h"
#include "base/unguessable_token.h"
#include "components/services/leveldb/public/mojom/leveldb.mojom.h"
#include "components/services/storage/dom_storage/dom_storage_database.h"
#include "third_party/leveldatabase/src/include/leveldb/cache.h"
#include "third_party/leveldatabase/src/include/leveldb/db.h"
namespace leveldb {
// A temporary wrapper around the Storage Service's DomStorageDatabase class,
// implemented behind the mojom interface facade consumed by
// LocalStorageContextMojo, SessionStorageContextMojo, and related classes. Note
// that this is never used through an actual message pipe, but always via direct
// method calls.
//
// TODO(https://crbug.com/1000959): Delete this class.
class LevelDBDatabaseImpl : public mojom::LevelDBDatabase {
public:
using OpenCallback = base::OnceCallback<void(mojom::DatabaseError)>;
~LevelDBDatabaseImpl() override;
static std::unique_ptr<LevelDBDatabaseImpl> OpenDirectory(
const leveldb_env::Options& options,
const base::FilePath& directory,
const std::string& dbname,
const base::Optional<base::trace_event::MemoryAllocatorDumpGuid>&
memory_dump_id,
scoped_refptr<base::SequencedTaskRunner> blocking_task_runner,
OpenCallback callback);
static std::unique_ptr<LevelDBDatabaseImpl> OpenInMemory(
const base::Optional<base::trace_event::MemoryAllocatorDumpGuid>&
memory_dump_id,
const std::string& tracking_name,
scoped_refptr<base::SequencedTaskRunner> blocking_task_runner,
OpenCallback callback);
base::SequenceBound<storage::DomStorageDatabase>& database() {
return database_;
}
const base::SequenceBound<storage::DomStorageDatabase>& database() const {
return database_;
}
// Overridden from LevelDBDatabase:
void Put(const std::vector<uint8_t>& key,
const std::vector<uint8_t>& value,
PutCallback callback) override;
void Delete(const std::vector<uint8_t>& key,
DeleteCallback callback) override;
void DeletePrefixed(const std::vector<uint8_t>& key_prefix,
DeletePrefixedCallback callback) override;
void RewriteDB(RewriteDBCallback callback) override;
void Write(std::vector<mojom::BatchedOperationPtr> operations,
WriteCallback callback) override;
void Get(const std::vector<uint8_t>& key, GetCallback callback) override;
void GetPrefixed(const std::vector<uint8_t>& key_prefix,
GetPrefixedCallback callback) override;
void GetMany(std::vector<mojom::GetManyRequestPtr> keys_or_prefixes,
GetManyCallback callback) override;
void CopyPrefixed(const std::vector<uint8_t>& source_key_prefix,
const std::vector<uint8_t>& destination_key_prefix,
CopyPrefixedCallback callback) override;
private:
using StatusAndKeyValues =
std::tuple<Status, std::vector<mojom::KeyValuePtr>>;
void OnDatabaseOpened(
OpenCallback callback,
base::SequenceBound<storage::DomStorageDatabase> database,
leveldb::Status status);
explicit LevelDBDatabaseImpl();
template <typename ResultType>
void RunDatabaseTask(
base::OnceCallback<ResultType(const storage::DomStorageDatabase&)> task,
base::OnceCallback<void(ResultType)> callback) {
auto wrapped_task = base::BindOnce(
[](base::OnceCallback<ResultType(const storage::DomStorageDatabase&)>
task,
base::OnceCallback<void(ResultType)> callback,
scoped_refptr<base::SequencedTaskRunner> callback_task_runner,
const storage::DomStorageDatabase& db) {
callback_task_runner->PostTask(
FROM_HERE,
base::BindOnce(std::move(callback), std::move(task).Run(db)));
},
std::move(task), std::move(callback),
base::SequencedTaskRunnerHandle::Get());
if (database_) {
database_.PostTaskWithThisObject(FROM_HERE, std::move(wrapped_task));
} else {
tasks_to_run_on_open_.push_back(std::move(wrapped_task));
}
}
base::SequenceBound<storage::DomStorageDatabase> database_;
using DatabaseTask =
base::OnceCallback<void(const storage::DomStorageDatabase&)>;
std::vector<DatabaseTask> tasks_to_run_on_open_;
base::WeakPtrFactory<LevelDBDatabaseImpl> weak_ptr_factory_{this};
DISALLOW_COPY_AND_ASSIGN(LevelDBDatabaseImpl);
};
} // namespace leveldb
#endif // COMPONENTS_SERVICES_LEVELDB_LEVELDB_DATABASE_IMPL_H_