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

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

Issue 11474036: Remove initial_sync_ended bits (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Add another test Created 8 years 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 22 matching lines...) Expand all
33 33
34 namespace syncer { 34 namespace syncer {
35 namespace syncable { 35 namespace syncable {
36 36
37 // This just has to be big enough to hold an UPDATE or INSERT statement that 37 // This just has to be big enough to hold an UPDATE or INSERT statement that
38 // modifies all the columns in the entry table. 38 // modifies all the columns in the entry table.
39 static const string::size_type kUpdateStatementBufferSize = 2048; 39 static const string::size_type kUpdateStatementBufferSize = 2048;
40 40
41 // Increment this version whenever updating DB tables. 41 // Increment this version whenever updating DB tables.
42 extern const int32 kCurrentDBVersion; // Global visibility for our unittest. 42 extern const int32 kCurrentDBVersion; // Global visibility for our unittest.
43 const int32 kCurrentDBVersion = 83; 43 const int32 kCurrentDBVersion = 84;
44 44
45 // Iterate over the fields of |entry| and bind each to |statement| for 45 // Iterate over the fields of |entry| and bind each to |statement| for
46 // updating. Returns the number of args bound. 46 // updating. Returns the number of args bound.
47 void BindFields(const EntryKernel& entry, 47 void BindFields(const EntryKernel& entry,
48 sql::Statement* statement) { 48 sql::Statement* statement) {
49 int index = 0; 49 int index = 0;
50 int i = 0; 50 int i = 0;
51 for (i = BEGIN_FIELDS; i < INT64_FIELDS_END; ++i) { 51 for (i = BEGIN_FIELDS; i < INT64_FIELDS_END; ++i) {
52 statement->BindInt64(index++, entry.ref(static_cast<Int64Field>(i))); 52 statement->BindInt64(index++, entry.ref(static_cast<Int64Field>(i)));
53 } 53 }
(...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after
190 } 190 }
191 191
192 bool DirectoryBackingStore::SaveChanges( 192 bool DirectoryBackingStore::SaveChanges(
193 const Directory::SaveChangesSnapshot& snapshot) { 193 const Directory::SaveChangesSnapshot& snapshot) {
194 DCHECK(CalledOnValidThread()); 194 DCHECK(CalledOnValidThread());
195 DCHECK(db_->is_open()); 195 DCHECK(db_->is_open());
196 196
197 // Back out early if there is nothing to write. 197 // Back out early if there is nothing to write.
198 bool save_info = 198 bool save_info =
199 (Directory::KERNEL_SHARE_INFO_DIRTY == snapshot.kernel_info_status); 199 (Directory::KERNEL_SHARE_INFO_DIRTY == snapshot.kernel_info_status);
200 if (snapshot.dirty_metas.size() < 1 && !save_info) 200 if (snapshot.dirty_metas.empty()
201 && snapshot.metahandles_to_purge.empty()
202 && !save_info) {
201 return true; 203 return true;
204 }
202 205
203 sql::Transaction transaction(db_.get()); 206 sql::Transaction transaction(db_.get());
204 if (!transaction.Begin()) 207 if (!transaction.Begin())
205 return false; 208 return false;
206 209
207 for (EntryKernelSet::const_iterator i = snapshot.dirty_metas.begin(); 210 for (EntryKernelSet::const_iterator i = snapshot.dirty_metas.begin();
208 i != snapshot.dirty_metas.end(); ++i) { 211 i != snapshot.dirty_metas.end(); ++i) {
209 DCHECK(i->is_dirty()); 212 DCHECK(i->is_dirty());
210 if (!SaveEntryToDB(*i)) 213 if (!SaveEntryToDB(*i))
211 return false; 214 return false;
(...skipping 17 matching lines...) Expand all
229 info.notification_state.size()); 232 info.notification_state.size());
230 s1.BindBlob(3, info.bag_of_chips.data(), info.bag_of_chips.size()); 233 s1.BindBlob(3, info.bag_of_chips.data(), info.bag_of_chips.size());
231 234
232 if (!s1.Run()) 235 if (!s1.Run())
233 return false; 236 return false;
234 DCHECK_EQ(db_->GetLastChangeCount(), 1); 237 DCHECK_EQ(db_->GetLastChangeCount(), 1);
235 238
236 sql::Statement s2(db_->GetCachedStatement( 239 sql::Statement s2(db_->GetCachedStatement(
237 SQL_FROM_HERE, 240 SQL_FROM_HERE,
238 "INSERT OR REPLACE " 241 "INSERT OR REPLACE "
239 "INTO models (model_id, progress_marker, initial_sync_ended, " 242 "INTO models (model_id, progress_marker, transaction_version) "
240 " transaction_version) " 243 "VALUES (?, ?, ?)"));
241 "VALUES (?, ?, ?, ?)"));
242 244
243 for (int i = FIRST_REAL_MODEL_TYPE; i < MODEL_TYPE_COUNT; ++i) { 245 for (int i = FIRST_REAL_MODEL_TYPE; i < MODEL_TYPE_COUNT; ++i) {
244 // We persist not ModelType but rather a protobuf-derived ID. 246 // We persist not ModelType but rather a protobuf-derived ID.
245 string model_id = ModelTypeEnumToModelId(ModelTypeFromInt(i)); 247 string model_id = ModelTypeEnumToModelId(ModelTypeFromInt(i));
246 string progress_marker; 248 string progress_marker;
247 info.download_progress[i].SerializeToString(&progress_marker); 249 info.download_progress[i].SerializeToString(&progress_marker);
248 s2.BindBlob(0, model_id.data(), model_id.length()); 250 s2.BindBlob(0, model_id.data(), model_id.length());
249 s2.BindBlob(1, progress_marker.data(), progress_marker.length()); 251 s2.BindBlob(1, progress_marker.data(), progress_marker.length());
250 s2.BindBool(2, info.initial_sync_ended.Has(ModelTypeFromInt(i))); 252 s2.BindInt64(2, info.transaction_version[i]);
251 s2.BindInt64(3, info.transaction_version[i]);
252 if (!s2.Run()) 253 if (!s2.Run())
253 return false; 254 return false;
254 DCHECK_EQ(db_->GetLastChangeCount(), 1); 255 DCHECK_EQ(db_->GetLastChangeCount(), 1);
255 s2.Reset(true); 256 s2.Reset(true);
256 } 257 }
257 } 258 }
258 259
259 return transaction.Commit(); 260 return transaction.Commit();
260 } 261 }
261 262
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after
357 if (MigrateVersion81To82()) 358 if (MigrateVersion81To82())
358 version_on_disk = 82; 359 version_on_disk = 82;
359 } 360 }
360 361
361 // Version 83 migration added transaction_version column per sync entry. 362 // Version 83 migration added transaction_version column per sync entry.
362 if (version_on_disk == 82) { 363 if (version_on_disk == 82) {
363 if (MigrateVersion82To83()) 364 if (MigrateVersion82To83())
364 version_on_disk = 83; 365 version_on_disk = 83;
365 } 366 }
366 367
368 // Version 84 migration removes the initial_sync_ended bits.
369 if (version_on_disk == 83) {
370 if (MigrateVersion83To84())
371 version_on_disk = 84;
372 }
373
367 // If one of the migrations requested it, drop columns that aren't current. 374 // If one of the migrations requested it, drop columns that aren't current.
368 // It's only safe to do this after migrating all the way to the current 375 // It's only safe to do this after migrating all the way to the current
369 // version. 376 // version.
370 if (version_on_disk == kCurrentDBVersion && needs_column_refresh_) { 377 if (version_on_disk == kCurrentDBVersion && needs_column_refresh_) {
371 if (!RefreshColumns()) 378 if (!RefreshColumns())
372 version_on_disk = 0; 379 version_on_disk = 0;
373 } 380 }
374 381
375 // A final, alternative catch-all migration to simply re-sync everything. 382 // A final, alternative catch-all migration to simply re-sync everything.
376 // 383 //
377 // TODO(rlarocque): It's wrong to recreate the database here unless the higher 384 // TODO(rlarocque): It's wrong to recreate the database here unless the higher
rlarocque 2012/12/12 01:19:16 I've been meaning to delete this comment for a whi
378 // layers were expecting us to do so. See crbug.com/103824. We must leave 385 // layers were expecting us to do so. See crbug.com/103824. We must leave
379 // this code as is for now because this is the code that ends up creating the 386 // this code as is for now because this is the code that ends up creating the
380 // database in the first time sync case, where the higher layers are expecting 387 // database in the first time sync case, where the higher layers are expecting
381 // us to create a fresh database. The solution to this should be to implement 388 // us to create a fresh database. The solution to this should be to implement
382 // crbug.com/105018. 389 // crbug.com/105018.
383 if (version_on_disk != kCurrentDBVersion) { 390 if (version_on_disk != kCurrentDBVersion) {
384 if (version_on_disk > kCurrentDBVersion) 391 if (version_on_disk > kCurrentDBVersion)
385 return false; 392 return false;
386 393
387 // Fallback (re-sync everything) migration path. 394 // Fallback (re-sync everything) migration path.
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after
495 s.ColumnBlobAsString(4, &(info->kernel_info.bag_of_chips)); 502 s.ColumnBlobAsString(4, &(info->kernel_info.bag_of_chips));
496 503
497 // Verify there was only one row returned. 504 // Verify there was only one row returned.
498 DCHECK(!s.Step()); 505 DCHECK(!s.Step());
499 DCHECK(s.Succeeded()); 506 DCHECK(s.Succeeded());
500 } 507 }
501 508
502 { 509 {
503 sql::Statement s( 510 sql::Statement s(
504 db_->GetUniqueStatement( 511 db_->GetUniqueStatement(
505 "SELECT model_id, progress_marker, initial_sync_ended, " 512 "SELECT model_id, progress_marker, "
506 "transaction_version FROM models")); 513 "transaction_version FROM models"));
507 514
508 while (s.Step()) { 515 while (s.Step()) {
509 ModelType type = ModelIdToModelTypeEnum(s.ColumnBlob(0), 516 ModelType type = ModelIdToModelTypeEnum(s.ColumnBlob(0),
510 s.ColumnByteLength(0)); 517 s.ColumnByteLength(0));
511 if (type != UNSPECIFIED && type != TOP_LEVEL_FOLDER) { 518 if (type != UNSPECIFIED && type != TOP_LEVEL_FOLDER) {
512 info->kernel_info.download_progress[type].ParseFromArray( 519 info->kernel_info.download_progress[type].ParseFromArray(
513 s.ColumnBlob(1), s.ColumnByteLength(1)); 520 s.ColumnBlob(1), s.ColumnByteLength(1));
514 if (s.ColumnBool(2)) 521 info->kernel_info.transaction_version[type] = s.ColumnInt64(2);
515 info->kernel_info.initial_sync_ended.Put(type);
516 info->kernel_info.transaction_version[type] = s.ColumnInt64(3);
517 } 522 }
518 } 523 }
519 if (!s.Succeeded()) 524 if (!s.Succeeded())
520 return false; 525 return false;
521 } 526 }
522 { 527 {
523 sql::Statement s( 528 sql::Statement s(
524 db_->GetUniqueStatement( 529 db_->GetUniqueStatement(
525 "SELECT MAX(metahandle) FROM metas")); 530 "SELECT MAX(metahandle) FROM metas"));
526 if (!s.Step()) 531 if (!s.Step())
(...skipping 374 matching lines...) Expand 10 before | Expand all | Expand 10 after
901 // boolean initial_sync_ended 906 // boolean initial_sync_ended
902 // In version 75, we deprecated the integer-valued last_download_timestamp, 907 // In version 75, we deprecated the integer-valued last_download_timestamp,
903 // using insted a protobuf-valued progress_marker field: 908 // using insted a protobuf-valued progress_marker field:
904 // blob progress_marker 909 // blob progress_marker
905 // The progress_marker values are initialized from the value of 910 // The progress_marker values are initialized from the value of
906 // last_download_timestamp, thereby preserving the download state. 911 // last_download_timestamp, thereby preserving the download state.
907 912
908 // Move aside the old table and create a new empty one at the current schema. 913 // Move aside the old table and create a new empty one at the current schema.
909 if (!db_->Execute("ALTER TABLE models RENAME TO temp_models")) 914 if (!db_->Execute("ALTER TABLE models RENAME TO temp_models"))
910 return false; 915 return false;
911 if (!CreateModelsTable()) 916 if (!CreateV75ModelsTable())
912 return false; 917 return false;
913 918
914 sql::Statement query(db_->GetUniqueStatement( 919 sql::Statement query(db_->GetUniqueStatement(
915 "SELECT model_id, last_download_timestamp, initial_sync_ended " 920 "SELECT model_id, last_download_timestamp, initial_sync_ended "
916 "FROM temp_models")); 921 "FROM temp_models"));
917 922
918 sql::Statement update(db_->GetUniqueStatement( 923 sql::Statement update(db_->GetUniqueStatement(
919 "INSERT INTO models (model_id, " 924 "INSERT INTO models (model_id, "
920 "progress_marker, initial_sync_ended) VALUES (?, ?, ?)")); 925 "progress_marker, initial_sync_ended) VALUES (?, ?, ?)"));
921 926
(...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after
1052 return false; 1057 return false;
1053 put_ordinals.Reset(true); 1058 put_ordinals.Reset(true);
1054 } 1059 }
1055 1060
1056 SetVersion(81); 1061 SetVersion(81);
1057 needs_column_refresh_ = true; 1062 needs_column_refresh_ = true;
1058 return true; 1063 return true;
1059 } 1064 }
1060 1065
1061 bool DirectoryBackingStore::MigrateVersion81To82() { 1066 bool DirectoryBackingStore::MigrateVersion81To82() {
1062 // Version 82 added transaction_version to kernel info. But if user is 1067 // Version 82 added transaction_version to kernel info. But if user is
rlarocque 2012/12/12 01:19:16 This is the wrong way to handle a change in the Cr
1063 // migrating from 74 or before, 74->75 migration would recreate models table 1068 // migrating from 74 or before, 74->75 migration would recreate models table
1064 // that already has transaction_version column. 1069 // that already has transaction_version column.
1065 if (db_->DoesColumnExist("models", "transaction_version")) { 1070 if (db_->DoesColumnExist("models", "transaction_version")) {
1066 SetVersion(82); 1071 SetVersion(82);
1067 return true; 1072 return true;
1068 } 1073 }
1069 1074
1070 if (!db_->Execute( 1075 if (!db_->Execute(
1071 "ALTER TABLE models ADD COLUMN transaction_version BIGINT default 0")) 1076 "ALTER TABLE models ADD COLUMN transaction_version BIGINT default 0"))
1072 return false; 1077 return false;
(...skipping 11 matching lines...) Expand all
1084 "ALTER TABLE metas ADD COLUMN transaction_version BIGINT default 0")) 1089 "ALTER TABLE metas ADD COLUMN transaction_version BIGINT default 0"))
1085 return false; 1090 return false;
1086 sql::Statement update(db_->GetUniqueStatement( 1091 sql::Statement update(db_->GetUniqueStatement(
1087 "UPDATE metas SET transaction_version = 0")); 1092 "UPDATE metas SET transaction_version = 0"));
1088 if (!update.Run()) 1093 if (!update.Run())
1089 return false; 1094 return false;
1090 SetVersion(83); 1095 SetVersion(83);
1091 return true; 1096 return true;
1092 } 1097 }
1093 1098
1099
1100 bool DirectoryBackingStore::MigrateVersion83To84() {
1101 // Version 84 removes the initial_sync_ended flag.
1102 if (!db_->Execute("ALTER TABLE models RENAME TO temp_models"))
1103 return false;
1104 if (!CreateModelsTable())
1105 return false;
1106 if (!db_->Execute("INSERT INTO models SELECT "
1107 "model_id, progress_marker, transaction_version "
1108 "FROM temp_models")) {
1109 return false;
1110 }
1111 SafeDropTable("temp_models");
1112 SetVersion(84);
1113 return true;
1114 }
1115
1094 bool DirectoryBackingStore::CreateTables() { 1116 bool DirectoryBackingStore::CreateTables() {
1095 DVLOG(1) << "First run, creating tables"; 1117 DVLOG(1) << "First run, creating tables";
1096 // Create two little tables share_version and share_info 1118 // Create two little tables share_version and share_info
1097 if (!db_->Execute( 1119 if (!db_->Execute(
1098 "CREATE TABLE share_version (" 1120 "CREATE TABLE share_version ("
1099 "id VARCHAR(128) primary key, data INT)")) { 1121 "id VARCHAR(128) primary key, data INT)")) {
1100 return false; 1122 return false;
1101 } 1123 }
1102 1124
1103 { 1125 {
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
1181 return db_->Execute( 1203 return db_->Execute(
1182 "CREATE TABLE models (" 1204 "CREATE TABLE models ("
1183 "model_id BLOB primary key, " 1205 "model_id BLOB primary key, "
1184 "last_download_timestamp INT, " 1206 "last_download_timestamp INT, "
1185 // Gets set if the syncer ever gets updates from the 1207 // Gets set if the syncer ever gets updates from the
1186 // server and the server returns 0. Lets us detect the 1208 // server and the server returns 0. Lets us detect the
1187 // end of the initial sync. 1209 // end of the initial sync.
1188 "initial_sync_ended BOOLEAN default 0)"); 1210 "initial_sync_ended BOOLEAN default 0)");
1189 } 1211 }
1190 1212
1213 bool DirectoryBackingStore::CreateV75ModelsTable() {
1214 // This is an old schema for the Models table, used from versions 75 to 83.
1215 return db_->Execute(
1216 "CREATE TABLE models ("
1217 "model_id BLOB primary key, "
1218 "progress_marker BLOB, "
1219 // Gets set if the syncer ever gets updates from the
1220 // server and the server returns 0. Lets us detect the
1221 // end of the initial sync.
1222 "initial_sync_ended BOOLEAN default 0, "
1223 "transaction_version BIGINT default 0)");
1224 }
1225
1191 bool DirectoryBackingStore::CreateModelsTable() { 1226 bool DirectoryBackingStore::CreateModelsTable() {
1192 // This is the current schema for the Models table, from version 81 1227 // This is the current schema for the Models table, from version 81
1193 // onward. If you change the schema, you'll probably want to double-check 1228 // onward. If you change the schema, you'll probably want to double-check
1194 // the use of this function in the v74-v75 migration. 1229 // the use of this function in the v83-v84 migration.
1195 return db_->Execute( 1230 return db_->Execute(
1196 "CREATE TABLE models (" 1231 "CREATE TABLE models ("
1197 "model_id BLOB primary key, " 1232 "model_id BLOB primary key, "
1198 "progress_marker BLOB, " 1233 "progress_marker BLOB, "
1199 // Gets set if the syncer ever gets updates from the 1234 // Gets set if the syncer ever gets updates from the
1200 // server and the server returns 0. Lets us detect the 1235 // server and the server returns 0. Lets us detect the
1201 // end of the initial sync. 1236 // end of the initial sync.
1202 "initial_sync_ended BOOLEAN default 0, "
1203 "transaction_version BIGINT default 0)"); 1237 "transaction_version BIGINT default 0)");
1204 } 1238 }
1205 1239
1206 bool DirectoryBackingStore::CreateShareInfoTable(bool is_temporary) { 1240 bool DirectoryBackingStore::CreateShareInfoTable(bool is_temporary) {
1207 const char* name = is_temporary ? "temp_share_info" : "share_info"; 1241 const char* name = is_temporary ? "temp_share_info" : "share_info";
1208 string query = "CREATE TABLE "; 1242 string query = "CREATE TABLE ";
1209 query.append(name); 1243 query.append(name);
1210 // This is the current schema for the ShareInfo table, from version 76 1244 // This is the current schema for the ShareInfo table, from version 76
1211 // onward. 1245 // onward.
1212 query.append(" (" 1246 query.append(" ("
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
1266 bool prev_exists = (ids_set.find(entry->ref(PREV_ID).value()) != end); 1300 bool prev_exists = (ids_set.find(entry->ref(PREV_ID).value()) != end);
1267 bool parent_exists = (ids_set.find(entry->ref(PARENT_ID).value()) != end); 1301 bool parent_exists = (ids_set.find(entry->ref(PARENT_ID).value()) != end);
1268 bool next_exists = (ids_set.find(entry->ref(NEXT_ID).value()) != end); 1302 bool next_exists = (ids_set.find(entry->ref(NEXT_ID).value()) != end);
1269 is_ok = is_ok && prev_exists && parent_exists && next_exists; 1303 is_ok = is_ok && prev_exists && parent_exists && next_exists;
1270 } 1304 }
1271 return is_ok; 1305 return is_ok;
1272 } 1306 }
1273 1307
1274 } // namespace syncable 1308 } // namespace syncable
1275 } // namespace syncer 1309 } // namespace syncer
OLDNEW
« no previous file with comments | « sync/syncable/directory_backing_store.h ('k') | sync/syncable/directory_backing_store_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698