#include "chrome/browser/sync_file_system/drive_backend/metadata_database.h"
#include <algorithm>
#include <memory>
#include <string_view>
#include <unordered_set>
#include <utility>
#include "base/command_line.h"
#include "base/containers/adapters.h"
#include "base/containers/contains.h"
#include "base/files/file_path.h"
#include "base/files/file_util.h"
#include "base/functional/bind.h"
#include "base/location.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_util.h"
#include "base/task/single_thread_task_runner.h"
#include "base/threading/scoped_blocking_call.h"
#include "chrome/browser/sync_file_system/drive_backend/drive_backend_constants.h"
#include "chrome/browser/sync_file_system/drive_backend/drive_backend_util.h"
#include "chrome/browser/sync_file_system/drive_backend/leveldb_wrapper.h"
#include "chrome/browser/sync_file_system/drive_backend/metadata_database.pb.h"
#include "chrome/browser/sync_file_system/drive_backend/metadata_database_index.h"
#include "chrome/browser/sync_file_system/drive_backend/metadata_database_index_interface.h"
#include "chrome/browser/sync_file_system/drive_backend/metadata_database_index_on_disk.h"
#include "chrome/browser/sync_file_system/drive_backend/metadata_db_migration_util.h"
#include "chrome/browser/sync_file_system/logger.h"
#include "chrome/browser/sync_file_system/syncable_file_system_util.h"
#include "components/drive/drive_api_util.h"
#include "google_apis/drive/drive_api_parser.h"
#include "storage/common/file_system/file_system_util.h"
#include "third_party/leveldatabase/env_chromium.h"
#include "third_party/leveldatabase/leveldb_chrome.h"
#include "third_party/leveldatabase/src/include/leveldb/db.h"
#include "third_party/leveldatabase/src/include/leveldb/status.h"
#include "third_party/leveldatabase/src/include/leveldb/write_batch.h"
namespace sync_file_system {
namespace drive_backend {
namespace {
const char kDisableMetadataDatabaseOnDisk[] = …;
std::string FileKindToString(FileKind file_kind) { … }
base::FilePath ReverseConcatPathComponents(
const std::vector<base::FilePath>& components) { … }
void PopulateFileDetailsByFileResource(
const google_apis::FileResource& file_resource,
FileDetails* details) { … }
std::unique_ptr<FileMetadata> CreateFileMetadataFromFileResource(
int64_t change_id,
const google_apis::FileResource& resource) { … }
std::unique_ptr<FileMetadata> CreateFileMetadataFromChangeResource(
const google_apis::ChangeResource& change) { … }
std::unique_ptr<FileMetadata> CreateDeletedFileMetadata(
int64_t change_id,
const std::string& file_id) { … }
std::unique_ptr<FileTracker> CreateSyncRootTracker(
int64_t tracker_id,
const FileMetadata& sync_root_metadata) { … }
std::unique_ptr<FileTracker> CreateInitialAppRootTracker(
int64_t tracker_id,
int64_t parent_tracker_id,
const FileMetadata& app_root_metadata) { … }
std::unique_ptr<FileTracker> CloneFileTracker(const FileTracker* obj) { … }
bool IsDatabaseEmpty(LevelDBWrapper* db) { … }
SyncStatusCode OpenDatabase(const base::FilePath& path,
leveldb::Env* env_override,
std::unique_ptr<LevelDBWrapper>* db_out,
bool* created) { … }
SyncStatusCode MigrateDatabaseIfNeeded(LevelDBWrapper* db) { … }
bool HasInvalidTitle(const std::string& title) { … }
void MarkTrackerSetDirty(const TrackerIDSet& trackers,
MetadataDatabaseIndexInterface* index) { … }
void MarkTrackersDirtyByPath(int64_t parent_tracker_id,
const std::string& title,
MetadataDatabaseIndexInterface* index) { … }
void MarkTrackersDirtyByFileID(const std::string& file_id,
MetadataDatabaseIndexInterface* index) { … }
void MarkTrackersDirtyRecursively(int64_t root_tracker_id,
MetadataDatabaseIndexInterface* index) { … }
void RemoveAllDescendantTrackers(int64_t root_tracker_id,
MetadataDatabaseIndexInterface* index) { … }
bool FilterFileTrackersByParent(const MetadataDatabaseIndexInterface* index,
const TrackerIDSet& trackers,
int64_t parent_tracker_id,
FileTracker* tracker_out) { … }
bool FilterFileTrackersByParentAndTitle(
const MetadataDatabaseIndexInterface* index,
const TrackerIDSet& trackers,
int64_t parent_tracker_id,
const std::string& title,
FileTracker* result) { … }
bool FilterFileTrackersByFileID(
const MetadataDatabaseIndexInterface* index,
const TrackerIDSet& trackers,
const std::string& file_id,
FileTracker* tracker_out) { … }
enum DirtyingOption { … };
void ActivateFileTracker(int64_t tracker_id,
int dirtying_options,
MetadataDatabaseIndexInterface* index) { … }
void DeactivateFileTracker(int64_t tracker_id,
int dirtying_options,
MetadataDatabaseIndexInterface* index) { … }
void RemoveFileTracker(int64_t tracker_id,
int dirtying_options,
MetadataDatabaseIndexInterface* index) { … }
}
std::unique_ptr<MetadataDatabase> MetadataDatabase::Create(
const base::FilePath& database_path,
leveldb::Env* env_override,
SyncStatusCode* status_out) { … }
std::unique_ptr<MetadataDatabase> MetadataDatabase::CreateInternal(
const base::FilePath& database_path,
leveldb::Env* env_override,
bool enable_on_disk_index,
SyncStatusCode* status_out) { … }
SyncStatusCode MetadataDatabase::CreateForTesting(
std::unique_ptr<LevelDBWrapper> db,
bool enable_on_disk_index,
std::unique_ptr<MetadataDatabase>* metadata_database_out) { … }
MetadataDatabase::~MetadataDatabase() { … }
void MetadataDatabase::ClearDatabase(
std::unique_ptr<MetadataDatabase> metadata_database) { … }
int64_t MetadataDatabase::GetLargestFetchedChangeID() const { … }
int64_t MetadataDatabase::GetSyncRootTrackerID() const { … }
int64_t MetadataDatabase::GetLargestKnownChangeID() const { … }
void MetadataDatabase::UpdateLargestKnownChangeID(int64_t change_id) { … }
bool MetadataDatabase::NeedsSyncRootRevalidation() const { … }
bool MetadataDatabase::HasSyncRoot() const { … }
SyncStatusCode MetadataDatabase::PopulateInitialData(
int64_t largest_change_id,
const google_apis::FileResource& sync_root_folder,
const std::vector<std::unique_ptr<google_apis::FileResource>>&
app_root_folders) { … }
bool MetadataDatabase::IsAppEnabled(const std::string& app_id) const { … }
SyncStatusCode MetadataDatabase::RegisterApp(const std::string& app_id,
const std::string& folder_id) { … }
SyncStatusCode MetadataDatabase::DisableApp(const std::string& app_id) { … }
SyncStatusCode MetadataDatabase::EnableApp(const std::string& app_id) { … }
SyncStatusCode MetadataDatabase::UnregisterApp(const std::string& app_id) { … }
bool MetadataDatabase::FindAppRootTracker(const std::string& app_id,
FileTracker* tracker_out) const { … }
bool MetadataDatabase::FindFileByFileID(const std::string& file_id,
FileMetadata* metadata_out) const { … }
bool MetadataDatabase::FindTrackersByFileID(const std::string& file_id,
TrackerIDSet* trackers_out) const { … }
bool MetadataDatabase::FindTrackersByParentAndTitle(
int64_t parent_tracker_id,
const std::string& title,
TrackerIDSet* trackers_out) const { … }
bool MetadataDatabase::FindTrackerByTrackerID(int64_t tracker_id,
FileTracker* tracker_out) const { … }
bool MetadataDatabase::BuildPathForTracker(int64_t tracker_id,
base::FilePath* path) const { … }
base::FilePath MetadataDatabase::BuildDisplayPathForTracker(
const FileTracker& tracker) const { … }
bool MetadataDatabase::FindNearestActiveAncestor(
const std::string& app_id,
const base::FilePath& full_path,
FileTracker* tracker_out,
base::FilePath* path_out) const { … }
SyncStatusCode MetadataDatabase::UpdateByChangeList(
int64_t largest_change_id,
std::vector<std::unique_ptr<google_apis::ChangeResource>> changes) { … }
SyncStatusCode MetadataDatabase::UpdateByFileResource(
const google_apis::FileResource& resource) { … }
SyncStatusCode MetadataDatabase::UpdateByFileResourceList(
std::vector<std::unique_ptr<google_apis::FileResource>> resources) { … }
SyncStatusCode MetadataDatabase::UpdateByDeletedRemoteFile(
const std::string& file_id) { … }
SyncStatusCode MetadataDatabase::UpdateByDeletedRemoteFileList(
const FileIDList& file_ids) { … }
SyncStatusCode MetadataDatabase::ReplaceActiveTrackerWithNewResource(
int64_t parent_tracker_id,
const google_apis::FileResource& resource) { … }
SyncStatusCode MetadataDatabase::PopulateFolderByChildList(
const std::string& folder_id,
const FileIDList& child_file_ids) { … }
SyncStatusCode MetadataDatabase::UpdateTracker(
int64_t tracker_id,
const FileDetails& updated_details) { … }
MetadataDatabase::ActivationStatus MetadataDatabase::TryActivateTracker(
int64_t parent_tracker_id,
const std::string& file_id,
SyncStatusCode* status_out) { … }
void MetadataDatabase::DemoteTracker(int64_t tracker_id) { … }
bool MetadataDatabase::PromoteDemotedTrackers() { … }
void MetadataDatabase::PromoteDemotedTracker(int64_t tracker_id) { … }
bool MetadataDatabase::GetDirtyTracker(
FileTracker* tracker_out) const { … }
bool MetadataDatabase::HasDemotedDirtyTracker() const { … }
bool MetadataDatabase::HasDirtyTracker() const { … }
size_t MetadataDatabase::CountDirtyTracker() const { … }
bool MetadataDatabase::GetMultiParentFileTrackers(std::string* file_id_out,
TrackerIDSet* trackers_out) { … }
size_t MetadataDatabase::CountFileMetadata() const { … }
size_t MetadataDatabase::CountFileTracker() const { … }
bool MetadataDatabase::GetConflictingTrackers(TrackerIDSet* trackers_out) { … }
void MetadataDatabase::GetRegisteredAppIDs(std::vector<std::string>* app_ids) { … }
SyncStatusCode MetadataDatabase::SweepDirtyTrackers(
const std::vector<std::string>& file_ids) { … }
MetadataDatabase::MetadataDatabase(const base::FilePath& database_path,
bool enable_on_disk_index,
leveldb::Env* env_override)
: … { … }
SyncStatusCode MetadataDatabase::Initialize() { … }
void MetadataDatabase::CreateTrackerForParentAndFileID(
const FileTracker& parent_tracker,
const std::string& file_id) { … }
void MetadataDatabase::CreateTrackerForParentAndFileMetadata(
const FileTracker& parent_tracker,
const FileMetadata& file_metadata,
UpdateOption option) { … }
void MetadataDatabase::CreateTrackerInternal(const FileTracker& parent_tracker,
const std::string& file_id,
const FileDetails* details,
UpdateOption option) { … }
void MetadataDatabase::MaybeAddTrackersForNewFile(
const FileMetadata& metadata,
UpdateOption option) { … }
int64_t MetadataDatabase::IncrementTrackerID() { … }
bool MetadataDatabase::CanActivateTracker(const FileTracker& tracker) { … }
bool MetadataDatabase::ShouldKeepDirty(const FileTracker& tracker) const { … }
bool MetadataDatabase::HasDisabledAppRoot(const FileTracker& tracker) const { … }
bool MetadataDatabase::HasActiveTrackerForFileID(
const std::string& file_id) const { … }
bool MetadataDatabase::HasActiveTrackerForPath(int64_t parent_tracker_id,
const std::string& title) const { … }
void MetadataDatabase::RemoveUnneededTrackersForMissingFile(
const std::string& file_id) { … }
void MetadataDatabase::UpdateByFileMetadata(
const base::Location& from_where,
std::unique_ptr<FileMetadata> metadata,
UpdateOption option) { … }
SyncStatusCode MetadataDatabase::WriteToDatabase() { … }
base::Value::List MetadataDatabase::DumpFiles(const std::string& app_id) { … }
base::Value::List MetadataDatabase::DumpDatabase() { … }
bool MetadataDatabase::HasNewerFileMetadata(const std::string& file_id,
int64_t change_id) { … }
base::Value::List MetadataDatabase::DumpTrackers() { … }
base::Value::List MetadataDatabase::DumpMetadata() { … }
void MetadataDatabase::AttachSyncRoot(
const google_apis::FileResource& sync_root_folder) { … }
void MetadataDatabase::AttachInitialAppRoot(
const google_apis::FileResource& app_root_folder) { … }
bool MetadataDatabase::CanClearDirty(const FileTracker& tracker) { … }
}
}