#ifndef COMPONENTS_DRIVE_RESOURCE_METADATA_STORAGE_H_
#define COMPONENTS_DRIVE_RESOURCE_METADATA_STORAGE_H_
#include <stdint.h>
#include <map>
#include <memory>
#include <string>
#include <vector>
#include "base/files/file_path.h"
#include "base/memory/scoped_refptr.h"
#include "components/drive/drive.pb.h"
#include "components/drive/drive_export.h"
#include "components/drive/file_errors.h"
namespace base {
class SequencedTaskRunner;
}
namespace leveldb {
class DB;
class Iterator;
}
namespace drive {
class ResourceEntry;
class ResourceMetadataHeader;
namespace internal {
class COMPONENTS_DRIVE_EXPORT ResourceMetadataStorage {
public:
static constexpr int kDBVersion = 19;
class COMPONENTS_DRIVE_EXPORT Iterator {
public:
explicit Iterator(std::unique_ptr<leveldb::Iterator> it);
Iterator(const Iterator&) = delete;
Iterator& operator=(const Iterator&) = delete;
~Iterator();
bool IsAtEnd() const;
std::string GetID() const;
const ResourceEntry& GetValue() const;
void Advance();
bool HasError() const;
private:
ResourceEntry entry_;
std::unique_ptr<leveldb::Iterator> it_;
};
struct COMPONENTS_DRIVE_EXPORT RecoveredCacheInfo {
RecoveredCacheInfo();
~RecoveredCacheInfo();
bool is_dirty;
std::string md5;
std::string title;
};
using RecoveredCacheInfoMap = std::map<std::string, RecoveredCacheInfo>;
static bool UpgradeOldDB(const base::FilePath& directory_path);
ResourceMetadataStorage(const base::FilePath& directory_path,
base::SequencedTaskRunner* blocking_task_runner);
ResourceMetadataStorage(const ResourceMetadataStorage&) = delete;
ResourceMetadataStorage& operator=(const ResourceMetadataStorage&) = delete;
const base::FilePath& directory_path() const { return directory_path_; }
bool cache_file_scan_is_needed() const { return cache_file_scan_is_needed_; }
bool Initialize();
void Destroy();
void RecoverCacheInfoFromTrashedResourceMap(RecoveredCacheInfoMap* out_info);
FileError SetLargestChangestamp(int64_t largest_changestamp);
FileError GetLargestChangestamp(int64_t* largest_changestamp);
FileError GetStartPageToken(std::string* out_value);
FileError SetStartPageToken(const std::string& value);
FileError PutEntry(const ResourceEntry& entry);
FileError GetEntry(const std::string& id, ResourceEntry* out_entry);
FileError RemoveEntry(const std::string& id);
std::unique_ptr<Iterator> GetIterator();
FileError GetChild(const std::string& parent_id,
const std::string& child_name,
std::string* child_id) const;
FileError GetChildren(const std::string& parent_id,
std::vector<std::string>* children) const;
FileError GetIdByResourceId(const std::string& resource_id,
std::string* out_id) const;
private:
friend class ResourceMetadataStorageTest;
~ResourceMetadataStorage();
void DestroyOnBlockingPool();
static std::string GetChildEntryKey(const std::string& parent_id,
const std::string& child_name);
FileError PutHeader(const ResourceMetadataHeader& header);
FileError GetHeader(ResourceMetadataHeader* out_header) const;
bool CheckValidity();
const base::FilePath directory_path_;
bool cache_file_scan_is_needed_;
std::unique_ptr<leveldb::DB> resource_map_;
scoped_refptr<base::SequencedTaskRunner> blocking_task_runner_;
};
}
}
#endif