Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(609)

Side by Side Diff: sync/syncable/directory_backing_store.cc

Issue 10916174: Implement a bag of chips for sync. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Moving persistence Created 8 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "sync/syncable/directory_backing_store.h" 5 #include "sync/syncable/directory_backing_store.h"
6 6
7 #include "build/build_config.h" 7 #include "build/build_config.h"
8 8
9 #include <limits> 9 #include <limits>
10 10
(...skipping 21 matching lines...) Expand all
32 32
33 namespace syncer { 33 namespace syncer {
34 namespace syncable { 34 namespace syncable {
35 35
36 // This just has to be big enough to hold an UPDATE or INSERT statement that 36 // This just has to be big enough to hold an UPDATE or INSERT statement that
37 // modifies all the columns in the entry table. 37 // modifies all the columns in the entry table.
38 static const string::size_type kUpdateStatementBufferSize = 2048; 38 static const string::size_type kUpdateStatementBufferSize = 2048;
39 39
40 // Increment this version whenever updating DB tables. 40 // Increment this version whenever updating DB tables.
41 extern const int32 kCurrentDBVersion; // Global visibility for our unittest. 41 extern const int32 kCurrentDBVersion; // Global visibility for our unittest.
42 const int32 kCurrentDBVersion = 79; 42 const int32 kCurrentDBVersion = 80;
43 43
44 // Iterate over the fields of |entry| and bind each to |statement| for 44 // Iterate over the fields of |entry| and bind each to |statement| for
45 // updating. Returns the number of args bound. 45 // updating. Returns the number of args bound.
46 void BindFields(const EntryKernel& entry, 46 void BindFields(const EntryKernel& entry,
47 sql::Statement* statement) { 47 sql::Statement* statement) {
48 int index = 0; 48 int index = 0;
49 int i = 0; 49 int i = 0;
50 for (i = BEGIN_FIELDS; i < INT64_FIELDS_END; ++i) { 50 for (i = BEGIN_FIELDS; i < INT64_FIELDS_END; ++i) {
51 statement->BindInt64(index++, entry.ref(static_cast<Int64Field>(i))); 51 statement->BindInt64(index++, entry.ref(static_cast<Int64Field>(i)));
52 } 52 }
(...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after
194 if (!DeleteEntries(snapshot.metahandles_to_purge)) 194 if (!DeleteEntries(snapshot.metahandles_to_purge))
195 return false; 195 return false;
196 196
197 if (save_info) { 197 if (save_info) {
198 const Directory::PersistedKernelInfo& info = snapshot.kernel_info; 198 const Directory::PersistedKernelInfo& info = snapshot.kernel_info;
199 sql::Statement s1(db_->GetCachedStatement( 199 sql::Statement s1(db_->GetCachedStatement(
200 SQL_FROM_HERE, 200 SQL_FROM_HERE,
201 "UPDATE share_info " 201 "UPDATE share_info "
202 "SET store_birthday = ?, " 202 "SET store_birthday = ?, "
203 "next_id = ?, " 203 "next_id = ?, "
204 "notification_state = ?")); 204 "notification_state = ?, "
205 "bag_of_chips = ?"));
205 s1.BindString(0, info.store_birthday); 206 s1.BindString(0, info.store_birthday);
206 s1.BindInt64(1, info.next_id); 207 s1.BindInt64(1, info.next_id);
207 s1.BindBlob(2, info.notification_state.data(), 208 s1.BindBlob(2, info.notification_state.data(),
208 info.notification_state.size()); 209 info.notification_state.size());
210 s1.BindBlob(3, info.bag_of_chips.data(), info.bag_of_chips.size());
209 211
210 if (!s1.Run()) 212 if (!s1.Run())
211 return false; 213 return false;
212 DCHECK_EQ(db_->GetLastChangeCount(), 1); 214 DCHECK_EQ(db_->GetLastChangeCount(), 1);
213 215
214 sql::Statement s2(db_->GetCachedStatement( 216 sql::Statement s2(db_->GetCachedStatement(
215 SQL_FROM_HERE, 217 SQL_FROM_HERE,
216 "INSERT OR REPLACE " 218 "INSERT OR REPLACE "
217 "INTO models (model_id, progress_marker, initial_sync_ended) " 219 "INTO models (model_id, progress_marker, initial_sync_ended) "
218 "VALUES (?, ?, ?)")); 220 "VALUES (?, ?, ?)"));
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after
308 if (MigrateVersion77To78()) 310 if (MigrateVersion77To78())
309 version_on_disk = 78; 311 version_on_disk = 78;
310 } 312 }
311 313
312 // Version 79 migration is a one-time fix for some users in a bad state. 314 // Version 79 migration is a one-time fix for some users in a bad state.
313 if (version_on_disk == 78) { 315 if (version_on_disk == 78) {
314 if (MigrateVersion78To79()) 316 if (MigrateVersion78To79())
315 version_on_disk = 79; 317 version_on_disk = 79;
316 } 318 }
317 319
320 // Version 80 migration is adding the bag_of_chips column.
321 if (version_on_disk == 79) {
322 if (MigrateVersion79To80())
323 version_on_disk = 80;
324 }
325
318 // If one of the migrations requested it, drop columns that aren't current. 326 // If one of the migrations requested it, drop columns that aren't current.
319 // It's only safe to do this after migrating all the way to the current 327 // It's only safe to do this after migrating all the way to the current
320 // version. 328 // version.
321 if (version_on_disk == kCurrentDBVersion && needs_column_refresh_) { 329 if (version_on_disk == kCurrentDBVersion && needs_column_refresh_) {
322 if (!RefreshColumns()) 330 if (!RefreshColumns())
323 version_on_disk = 0; 331 version_on_disk = 0;
324 } 332 }
325 333
326 // A final, alternative catch-all migration to simply re-sync everything. 334 // A final, alternative catch-all migration to simply re-sync everything.
327 // 335 //
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
388 return false; 396 return false;
389 397
390 // Repeat the process for share_info. 398 // Repeat the process for share_info.
391 SafeDropTable("temp_share_info"); 399 SafeDropTable("temp_share_info");
392 if (!CreateShareInfoTable(true)) 400 if (!CreateShareInfoTable(true))
393 return false; 401 return false;
394 402
395 if (!db_->Execute( 403 if (!db_->Execute(
396 "INSERT INTO temp_share_info (id, name, store_birthday, " 404 "INSERT INTO temp_share_info (id, name, store_birthday, "
397 "db_create_version, db_create_time, next_id, cache_guid," 405 "db_create_version, db_create_time, next_id, cache_guid,"
398 "notification_state) " 406 "notification_state, bag_of_chips) "
399 "SELECT id, name, store_birthday, db_create_version, " 407 "SELECT id, name, store_birthday, db_create_version, "
400 "db_create_time, next_id, cache_guid, notification_state " 408 "db_create_time, next_id, cache_guid, notification_state, "
409 "bag_of_chips "
401 "FROM share_info")) 410 "FROM share_info"))
402 return false; 411 return false;
403 412
404 SafeDropTable("share_info"); 413 SafeDropTable("share_info");
405 if (!db_->Execute("ALTER TABLE temp_share_info RENAME TO share_info")) 414 if (!db_->Execute("ALTER TABLE temp_share_info RENAME TO share_info"))
406 return false; 415 return false;
407 416
408 needs_column_refresh_ = false; 417 needs_column_refresh_ = false;
409 return true; 418 return true;
410 } 419 }
(...skipping 11 matching lines...) Expand all
422 EntryKernel *kernel = UnpackEntry(&s); 431 EntryKernel *kernel = UnpackEntry(&s);
423 entry_bucket->insert(kernel); 432 entry_bucket->insert(kernel);
424 } 433 }
425 return s.Succeeded(); 434 return s.Succeeded();
426 } 435 }
427 436
428 bool DirectoryBackingStore::LoadInfo(Directory::KernelLoadInfo* info) { 437 bool DirectoryBackingStore::LoadInfo(Directory::KernelLoadInfo* info) {
429 { 438 {
430 sql::Statement s( 439 sql::Statement s(
431 db_->GetUniqueStatement( 440 db_->GetUniqueStatement(
432 "SELECT store_birthday, next_id, cache_guid, notification_state " 441 "SELECT store_birthday, next_id, cache_guid, notification_state, "
442 "bag_of_chips "
433 "FROM share_info")); 443 "FROM share_info"));
434 if (!s.Step()) 444 if (!s.Step())
435 return false; 445 return false;
436 446
437 info->kernel_info.store_birthday = s.ColumnString(0); 447 info->kernel_info.store_birthday = s.ColumnString(0);
438 info->kernel_info.next_id = s.ColumnInt64(1); 448 info->kernel_info.next_id = s.ColumnInt64(1);
439 info->cache_guid = s.ColumnString(2); 449 info->cache_guid = s.ColumnString(2);
440 s.ColumnBlobAsString(3, &(info->kernel_info.notification_state)); 450 s.ColumnBlobAsString(3, &(info->kernel_info.notification_state));
451 s.ColumnBlobAsString(4, &(info->kernel_info.bag_of_chips));
441 452
442 // Verify there was only one row returned. 453 // Verify there was only one row returned.
443 DCHECK(!s.Step()); 454 DCHECK(!s.Step());
444 DCHECK(s.Succeeded()); 455 DCHECK(s.Succeeded());
445 } 456 }
446 457
447 { 458 {
448 sql::Statement s( 459 sql::Statement s(
449 db_->GetUniqueStatement( 460 db_->GetUniqueStatement(
450 "SELECT model_id, progress_marker, initial_sync_ended " 461 "SELECT model_id, progress_marker, initial_sync_ended "
(...skipping 499 matching lines...) Expand 10 before | Expand all | Expand 10 after
950 // Some users are stuck with a DB that causes them to reuse existing IDs. We 961 // Some users are stuck with a DB that causes them to reuse existing IDs. We
951 // perform this one-time fixup on all users to help the few that are stuck. 962 // perform this one-time fixup on all users to help the few that are stuck.
952 // See crbug.com/142987 for details. 963 // See crbug.com/142987 for details.
953 if (!db_->Execute( 964 if (!db_->Execute(
954 "UPDATE share_info SET next_id = next_id - 65536")) { 965 "UPDATE share_info SET next_id = next_id - 65536")) {
955 return false; 966 return false;
956 } 967 }
957 SetVersion(79); 968 SetVersion(79);
958 return true; 969 return true;
959 } 970 }
971 bool DirectoryBackingStore::MigrateVersion79To80() {
972 if (!db_->Execute(
973 "ALTER TABLE share_info ADD COLUMN bag_of_chips BLOB"))
974 return false;
975 sql::Statement update(db_->GetUniqueStatement(
976 "UPDATE share_info SET bag_of_chips = ?"));
977 // An empty message is serialized to an empty string.
978 update.BindBlob(0, NULL, 0);
979 if (!update.Run())
980 return false;
981 SetVersion(80);
982 return true;
983 }
960 984
961 bool DirectoryBackingStore::CreateTables() { 985 bool DirectoryBackingStore::CreateTables() {
962 DVLOG(1) << "First run, creating tables"; 986 DVLOG(1) << "First run, creating tables";
963 // Create two little tables share_version and share_info 987 // Create two little tables share_version and share_info
964 if (!db_->Execute( 988 if (!db_->Execute(
965 "CREATE TABLE share_version (" 989 "CREATE TABLE share_version ("
966 "id VARCHAR(128) primary key, data INT)")) { 990 "id VARCHAR(128) primary key, data INT)")) {
967 return false; 991 return false;
968 } 992 }
969 993
(...skipping 15 matching lines...) Expand all
985 { 1009 {
986 sql::Statement s(db_->GetUniqueStatement( 1010 sql::Statement s(db_->GetUniqueStatement(
987 "INSERT INTO share_info VALUES" 1011 "INSERT INTO share_info VALUES"
988 "(?, " // id 1012 "(?, " // id
989 "?, " // name 1013 "?, " // name
990 "?, " // store_birthday 1014 "?, " // store_birthday
991 "?, " // db_create_version 1015 "?, " // db_create_version
992 "?, " // db_create_time 1016 "?, " // db_create_time
993 "-2, " // next_id 1017 "-2, " // next_id
994 "?, " // cache_guid 1018 "?, " // cache_guid
995 "?);")); // notification_state 1019 "?, " // notification_state
1020 "?);")); // bag_of_chips
996 s.BindString(0, dir_name_); // id 1021 s.BindString(0, dir_name_); // id
997 s.BindString(1, dir_name_); // name 1022 s.BindString(1, dir_name_); // name
998 s.BindString(2, ""); // store_birthday 1023 s.BindString(2, ""); // store_birthday
999 // TODO(akalin): Remove this unused db_create_version field. (Or 1024 // TODO(akalin): Remove this unused db_create_version field. (Or
1000 // actually use it for something.) http://crbug.com/118356 1025 // actually use it for something.) http://crbug.com/118356
1001 s.BindString(3, "Unknown"); // db_create_version 1026 s.BindString(3, "Unknown"); // db_create_version
1002 s.BindInt(4, static_cast<int32>(time(0))); // db_create_time 1027 s.BindInt(4, static_cast<int32>(time(0))); // db_create_time
1003 s.BindString(5, GenerateCacheGUID()); // cache_guid 1028 s.BindString(5, GenerateCacheGUID()); // cache_guid
1004 s.BindBlob(6, NULL, 0); // notification_state 1029 s.BindBlob(6, NULL, 0); // notification_state
1005 1030 s.BindBlob(7, NULL, 0); // bag_of_chips
1006 if (!s.Run()) 1031 if (!s.Run())
1007 return false; 1032 return false;
1008 } 1033 }
1009 1034
1010 if (!CreateModelsTable()) 1035 if (!CreateModelsTable())
1011 return false; 1036 return false;
1012 1037
1013 // Create the big metas table. 1038 // Create the big metas table.
1014 if (!CreateMetasTable(false)) 1039 if (!CreateMetasTable(false))
1015 return false; 1040 return false;
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
1071 query.append(name); 1096 query.append(name);
1072 // This is the current schema for the ShareInfo table, from version 76 1097 // This is the current schema for the ShareInfo table, from version 76
1073 // onward. 1098 // onward.
1074 query.append(" (" 1099 query.append(" ("
1075 "id TEXT primary key, " 1100 "id TEXT primary key, "
1076 "name TEXT, " 1101 "name TEXT, "
1077 "store_birthday TEXT, " 1102 "store_birthday TEXT, "
1078 "db_create_version TEXT, " 1103 "db_create_version TEXT, "
1079 "db_create_time INT, " 1104 "db_create_time INT, "
1080 "next_id INT default -2, " 1105 "next_id INT default -2, "
1081 "cache_guid TEXT "); 1106 "cache_guid TEXT, "
1082 1107 "notification_state BLOB, "
1083 query.append(", notification_state BLOB"); 1108 "bag_of_chips BLOB"
1084 query.append(")"); 1109 ")");
1085 return db_->Execute(query.c_str()); 1110 return db_->Execute(query.c_str());
1086 } 1111 }
1087 1112
1088 bool DirectoryBackingStore::CreateShareInfoTableVersion71( 1113 bool DirectoryBackingStore::CreateShareInfoTableVersion71(
1089 bool is_temporary) { 1114 bool is_temporary) {
1090 const char* name = is_temporary ? "temp_share_info" : "share_info"; 1115 const char* name = is_temporary ? "temp_share_info" : "share_info";
1091 string query = "CREATE TABLE "; 1116 string query = "CREATE TABLE ";
1092 query.append(name); 1117 query.append(name);
1093 // This is the schema for the ShareInfo table used from versions 71 to 72. 1118 // This is the schema for the ShareInfo table used from versions 71 to 72.
1094 query.append(" (" 1119 query.append(" ("
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
1128 bool prev_exists = (ids_set.find(entry->ref(PREV_ID).value()) != end); 1153 bool prev_exists = (ids_set.find(entry->ref(PREV_ID).value()) != end);
1129 bool parent_exists = (ids_set.find(entry->ref(PARENT_ID).value()) != end); 1154 bool parent_exists = (ids_set.find(entry->ref(PARENT_ID).value()) != end);
1130 bool next_exists = (ids_set.find(entry->ref(NEXT_ID).value()) != end); 1155 bool next_exists = (ids_set.find(entry->ref(NEXT_ID).value()) != end);
1131 is_ok = is_ok && prev_exists && parent_exists && next_exists; 1156 is_ok = is_ok && prev_exists && parent_exists && next_exists;
1132 } 1157 }
1133 return is_ok; 1158 return is_ok;
1134 } 1159 }
1135 1160
1136 } // namespace syncable 1161 } // namespace syncable
1137 } // namespace syncer 1162 } // namespace syncer
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698