Home | History | Annotate | Download | only in drive_backend
      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 
     21 namespace sync_file_system {
     22 namespace drive_backend {
     23 
     24 void PutVersionToDB(int64 version, LevelDBWrapper* db) {
     25   DCHECK(db);
     26   db->Put(kDatabaseVersionKey, base::Int64ToString(version));
     27 }
     28 
     29 void 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 
     39 void 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 
     48 void 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 
     58 void PutFileMetadataDeletionToDB(const std::string& file_id,
     59                                  LevelDBWrapper* db) {
     60   DCHECK(db);
     61   db->Delete(kFileMetadataKeyPrefix + file_id);
     62 }
     63 
     64 void PutFileTrackerDeletionToDB(int64 tracker_id, LevelDBWrapper* db) {
     65   DCHECK(db);
     66   db->Delete(kFileTrackerKeyPrefix + base::Int64ToString(tracker_id));
     67 }
     68 
     69 bool 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 
     77 bool IsAppRoot(const FileTracker& tracker) {
     78   return tracker.tracker_kind() == TRACKER_KIND_APP_ROOT ||
     79       tracker.tracker_kind() == TRACKER_KIND_DISABLED_APP_ROOT;
     80 }
     81 
     82 std::string GetTrackerTitle(const FileTracker& tracker) {
     83   if (tracker.has_synced_details())
     84     return tracker.synced_details().title();
     85   return std::string();
     86 }
     87 
     88 SyncStatusCode 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 
    155 bool 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 
    168 scoped_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