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. 4 5#include "chrome/browser/sync_file_system/drive_backend/drive_backend_util.h" 6 7#include "base/logging.h" 8#include "base/memory/scoped_vector.h" 9#include "base/strings/string_number_conversions.h" 10#include "base/strings/string_util.h" 11#include "base/threading/thread_restrictions.h" 12#include "chrome/browser/drive/drive_api_util.h" 13#include "chrome/browser/sync_file_system/drive_backend/drive_backend_constants.h" 14#include "chrome/browser/sync_file_system/drive_backend/leveldb_wrapper.h" 15#include "chrome/browser/sync_file_system/drive_backend/metadata_database.pb.h" 16#include "chrome/browser/sync_file_system/logger.h" 17#include "google_apis/drive/drive_api_parser.h" 18#include "google_apis/drive/gdata_wapi_parser.h" 19#include "third_party/leveldatabase/src/include/leveldb/status.h" 20 21namespace sync_file_system { 22namespace drive_backend { 23 24void PutVersionToDB(int64 version, LevelDBWrapper* db) { 25 DCHECK(db); 26 db->Put(kDatabaseVersionKey, base::Int64ToString(version)); 27} 28 29void PutServiceMetadataToDB(const ServiceMetadata& service_metadata, 30 LevelDBWrapper* db) { 31 DCHECK(db); 32 33 std::string value; 34 bool success = service_metadata.SerializeToString(&value); 35 DCHECK(success); 36 db->Put(kServiceMetadataKey, value); 37} 38 39void PutFileMetadataToDB(const FileMetadata& file, LevelDBWrapper* db) { 40 DCHECK(db); 41 42 std::string value; 43 bool success = file.SerializeToString(&value); 44 DCHECK(success); 45 db->Put(kFileMetadataKeyPrefix + file.file_id(), value); 46} 47 48void PutFileTrackerToDB(const FileTracker& tracker, LevelDBWrapper* db) { 49 DCHECK(db); 50 51 std::string value; 52 bool success = tracker.SerializeToString(&value); 53 DCHECK(success); 54 db->Put(kFileTrackerKeyPrefix + base::Int64ToString(tracker.tracker_id()), 55 value); 56} 57 58void PutFileMetadataDeletionToDB(const std::string& file_id, 59 LevelDBWrapper* db) { 60 DCHECK(db); 61 db->Delete(kFileMetadataKeyPrefix + file_id); 62} 63 64void PutFileTrackerDeletionToDB(int64 tracker_id, LevelDBWrapper* db) { 65 DCHECK(db); 66 db->Delete(kFileTrackerKeyPrefix + base::Int64ToString(tracker_id)); 67} 68 69bool HasFileAsParent(const FileDetails& details, const std::string& file_id) { 70 for (int i = 0; i < details.parent_folder_ids_size(); ++i) { 71 if (details.parent_folder_ids(i) == file_id) 72 return true; 73 } 74 return false; 75} 76 77bool IsAppRoot(const FileTracker& tracker) { 78 return tracker.tracker_kind() == TRACKER_KIND_APP_ROOT || 79 tracker.tracker_kind() == TRACKER_KIND_DISABLED_APP_ROOT; 80} 81 82std::string GetTrackerTitle(const FileTracker& tracker) { 83 if (tracker.has_synced_details()) 84 return tracker.synced_details().title(); 85 return std::string(); 86} 87 88SyncStatusCode GDataErrorCodeToSyncStatusCode( 89 google_apis::GDataErrorCode error) { 90 // NOTE: Please update DriveFileSyncService::UpdateServiceState when you add 91 // more error code mapping. 92 switch (error) { 93 case google_apis::HTTP_SUCCESS: 94 case google_apis::HTTP_CREATED: 95 case google_apis::HTTP_NO_CONTENT: 96 case google_apis::HTTP_FOUND: 97 return SYNC_STATUS_OK; 98 99 case google_apis::HTTP_NOT_MODIFIED: 100 return SYNC_STATUS_NOT_MODIFIED; 101 102 case google_apis::HTTP_CONFLICT: 103 case google_apis::HTTP_PRECONDITION: 104 return SYNC_STATUS_HAS_CONFLICT; 105 106 case google_apis::HTTP_UNAUTHORIZED: 107 return SYNC_STATUS_AUTHENTICATION_FAILED; 108 109 case google_apis::GDATA_NO_CONNECTION: 110 return SYNC_STATUS_NETWORK_ERROR; 111 112 case google_apis::HTTP_INTERNAL_SERVER_ERROR: 113 case google_apis::HTTP_BAD_GATEWAY: 114 case google_apis::HTTP_SERVICE_UNAVAILABLE: 115 case google_apis::GDATA_CANCELLED: 116 case google_apis::GDATA_NOT_READY: 117 return SYNC_STATUS_SERVICE_TEMPORARILY_UNAVAILABLE; 118 119 case google_apis::HTTP_NOT_FOUND: 120 case google_apis::HTTP_GONE: 121 return SYNC_FILE_ERROR_NOT_FOUND; 122 123 case google_apis::GDATA_FILE_ERROR: 124 return SYNC_FILE_ERROR_FAILED; 125 126 case google_apis::HTTP_FORBIDDEN: 127 return SYNC_STATUS_ACCESS_FORBIDDEN; 128 129 case google_apis::HTTP_RESUME_INCOMPLETE: 130 case google_apis::HTTP_BAD_REQUEST: 131 case google_apis::HTTP_LENGTH_REQUIRED: 132 case google_apis::HTTP_NOT_IMPLEMENTED: 133 case google_apis::GDATA_PARSE_ERROR: 134 case google_apis::GDATA_OTHER_ERROR: 135 return SYNC_STATUS_FAILED; 136 137 case google_apis::GDATA_NO_SPACE: 138 return SYNC_FILE_ERROR_NO_SPACE; 139 } 140 141 // There's a case where DriveService layer returns GDataErrorCode==-1 142 // when network is unavailable. (http://crbug.com/223042) 143 // TODO(kinuko,nhiroki): We should identify from where this undefined error 144 // code is coming. 145 if (error == -1) 146 return SYNC_STATUS_NETWORK_ERROR; 147 148 util::Log(logging::LOG_WARNING, 149 FROM_HERE, 150 "Got unexpected error: %d", 151 static_cast<int>(error)); 152 return SYNC_STATUS_FAILED; 153} 154 155bool RemovePrefix(const std::string& str, const std::string& prefix, 156 std::string* out) { 157 if (!StartsWithASCII(str, prefix, true)) { 158 if (out) 159 *out = str; 160 return false; 161 } 162 163 if (out) 164 *out = str.substr(prefix.size()); 165 return true; 166} 167 168scoped_ptr<ServiceMetadata> InitializeServiceMetadata(LevelDBWrapper* db) { 169 base::ThreadRestrictions::AssertIOAllowed(); 170 DCHECK(db); 171 172 scoped_ptr<ServiceMetadata> service_metadata; 173 174 std::string value; 175 leveldb::Status status = db->Get(kServiceMetadataKey, &value); 176 if (status.ok()) { 177 service_metadata.reset(new ServiceMetadata); 178 if (!service_metadata->ParseFromString(value)) 179 service_metadata.reset(); 180 } else if (status.IsNotFound()) { 181 service_metadata.reset(new ServiceMetadata); 182 service_metadata->set_next_tracker_id(1); 183 } 184 185 return service_metadata.Pass(); 186} 187 188} // namespace drive_backend 189} // namespace sync_file_system 190