Chromium Code Reviews| Index: chrome/browser/sync/syncable/directory_backing_store.cc |
| diff --git a/chrome/browser/sync/syncable/directory_backing_store.cc b/chrome/browser/sync/syncable/directory_backing_store.cc |
| index feefd91b7e6a3dc9deb189d46f19bd9247124b1d..d6e74c77f39d7ef05bd635feb250fe7fbfb00721 100644 |
| --- a/chrome/browser/sync/syncable/directory_backing_store.cc |
| +++ b/chrome/browser/sync/syncable/directory_backing_store.cc |
| @@ -44,7 +44,7 @@ static const string::size_type kUpdateStatementBufferSize = 2048; |
| // Increment this version whenever updating DB tables. |
| extern const int32 kCurrentDBVersion; // Global visibility for our unittest. |
| -const int32 kCurrentDBVersion = 74; |
| +const int32 kCurrentDBVersion = 75; |
| namespace { |
| @@ -411,11 +411,13 @@ bool DirectoryBackingStore::SaveChanges( |
| for (int i = FIRST_REAL_MODEL_TYPE; i < MODEL_TYPE_COUNT; ++i) { |
| SQLStatement op; |
| op.prepare(dbhandle, "INSERT OR REPLACE INTO models (model_id, " |
| - "last_download_timestamp, initial_sync_ended) VALUES ( ?, ?, ?)"); |
| + "progress_marker, initial_sync_ended) VALUES ( ?, ?, ?)"); |
| // We persist not ModelType but rather a protobuf-derived ID. |
| string model_id = ModelTypeEnumToModelId(ModelTypeFromInt(i)); |
| + string progress_marker; |
| + info.download_progress[i].SerializeToString(&progress_marker); |
| op.bind_blob(0, model_id.data(), model_id.length()); |
| - op.bind_int64(1, info.last_download_timestamp[i]); |
| + op.bind_blob(1, progress_marker.data(), progress_marker.length()); |
| op.bind_bool(2, info.initial_sync_ended[i]); |
| if (!(SQLITE_DONE == op.step() && |
| @@ -473,11 +475,18 @@ DirOpenResult DirectoryBackingStore::InitializeTables() { |
| version_on_disk = 73; |
| } |
| + // Version 74 added state for the autofill migration. |
| if (version_on_disk == 73) { |
| if (MigrateVersion73To74()) |
| version_on_disk = 74; |
| } |
| + // Version 75 migrated from int64-based timestamps to per-datatype tokens. |
| + if (version_on_disk == 74) { |
| + if (MigrateVersion74To75()) |
| + version_on_disk = 75; |
| + } |
| + |
| // If one of the migrations requested it, drop columns that aren't current. |
| // It's only safe to do this after migrating all the way to the current |
| // version. |
| @@ -606,14 +615,14 @@ bool DirectoryBackingStore::LoadInfo(Directory::KernelLoadInfo* info) { |
| { |
| SQLStatement query; |
| query.prepare(load_dbhandle_, |
| - "SELECT model_id, last_download_timestamp, initial_sync_ended " |
| + "SELECT model_id, progress_marker, initial_sync_ended " |
| "FROM models"); |
| while (SQLITE_ROW == query.step()) { |
| - string model_id; |
| - query.column_blob_as_string(0, &model_id); |
| - ModelType type = ModelIdToModelTypeEnum(model_id); |
| + ModelType type = ModelIdToModelTypeEnum(query.column_blob(0), |
| + query.column_bytes(0)); |
| if (type != UNSPECIFIED) { |
| - info->kernel_info.last_download_timestamp[type] = query.column_int64(1); |
| + info->kernel_info.download_progress[type].ParseFromArray( |
| + query.column_blob(1), query.column_bytes(1)); |
| info->kernel_info.initial_sync_ended[type] = query.column_bool(2); |
| } |
| } |
| @@ -709,14 +718,15 @@ void DirectoryBackingStore::DropAllTables() { |
| SafeDropTable("share_version"); |
| SafeDropTable("extended_attributes"); |
| SafeDropTable("models"); |
| + SafeDropTable("temp_models"); |
| needs_column_refresh_ = false; |
| } |
| // static |
| ModelType DirectoryBackingStore::ModelIdToModelTypeEnum( |
| - const string& model_id) { |
| + const void* data, int size) { |
| sync_pb::EntitySpecifics specifics; |
| - if (!specifics.ParseFromString(model_id)) |
| + if (!specifics.ParseFromArray(data, size)) |
| return syncable::UNSPECIFIED; |
| return syncable::GetModelTypeFromSpecifics(specifics); |
| } |
| @@ -900,7 +910,7 @@ bool DirectoryBackingStore::MigrateVersion68To69() { |
| // were removed from the share_info table. They were replaced by |
| // the 'models' table, which has these values on a per-datatype basis. |
| bool DirectoryBackingStore::MigrateVersion70To71() { |
| - if (SQLITE_DONE != CreateModelsTable()) |
| + if (SQLITE_DONE != CreateV71ModelsTable()) |
| return false; |
| // Move data from the old share_info columns to the new models table. |
| @@ -950,12 +960,15 @@ bool DirectoryBackingStore::MigrateVersion70To71() { |
| } |
| bool DirectoryBackingStore::MigrateVersion71To72() { |
| + // Version 72 removed a table 'extended_attributes', whose |
| + // contents didn't matter. |
| SafeDropTable("extended_attributes"); |
| SetVersion(72); |
| return true; |
| } |
| bool DirectoryBackingStore::MigrateVersion72To73() { |
| + // Version 73 added one column to the table 'share_info': notification_state |
| int result = |
| ExecQuery(load_dbhandle_, |
| "ALTER TABLE share_info ADD COLUMN notification_state BLOB"); |
| @@ -966,6 +979,13 @@ bool DirectoryBackingStore::MigrateVersion72To73() { |
| } |
| bool DirectoryBackingStore::MigrateVersion73To74() { |
| + // Version 74 added the following columns to the table 'share_info': |
| + // autofill_migration_state |
| + // bookmarks_added_during_autofill_migration |
| + // autofill_migration_time |
| + // autofill_entries_added_during_migration |
| + // autofill_profiles_added_during_migration |
| + |
| int result = |
| ExecQuery(load_dbhandle_, |
| "ALTER TABLE share_info ADD COLUMN autofill_migration_state " |
| @@ -1008,6 +1028,60 @@ bool DirectoryBackingStore::MigrateVersion73To74() { |
| return true; |
| } |
| +bool DirectoryBackingStore::MigrateVersion74To75() { |
| + // In version 74, there was a table 'models': |
| + // blob model_id (entity specifics, primary key) |
| + // int last_download_timestamp |
| + // boolean initial_sync_ended |
| + // In version 75, we deprecated the integer-valued last_download_timestamp, |
| + // using insted a protobuf-valued progress_marker field: |
| + // blob progress_marker |
| + // The progress_marker values are initialized from the value of |
| + // last_download_timestamp, thereby preserving the download state. |
| + |
| + // Move aside the old table and create a new empty one at the current schema. |
| + if (SQLITE_DONE != ExecQuery(load_dbhandle_, |
| + "ALTER TABLE models RENAME TO temp_models")) { |
| + return false; |
| + } |
| + if (!CreateModelsTable()) |
| + return false; |
| + |
| + SQLStatement query; |
| + query.prepare(load_dbhandle_, |
| + "SELECT model_id, last_download_timestamp, initial_sync_ended " |
| + "FROM temp_models"); |
| + while (SQLITE_ROW == query.step()) { |
| + ModelType type = ModelIdToModelTypeEnum(query.column_blob(0), |
| + query.column_bytes(0)); |
| + if (type != UNSPECIFIED) { |
|
tim (not reviewing)
2011/01/11 19:14:23
TOP_LEVEL_FOLDER?
ncarter (slow)
2011/01/13 00:06:13
Added, thanks. The implementatation of the called
|
| + // Set the |timestamp_token_for_migration| on a new |
| + // DataTypeProgressMarker, using the old value of last_download_timestamp. |
| + // The server will turn this into a real token on our behalf the next |
| + // time we check for updates. |
| + sync_pb::DataTypeProgressMarker progress_marker; |
| + progress_marker.set_data_type_id( |
| + GetExtensionFieldNumberFromModelType(type)); |
| + progress_marker.set_timestamp_token_for_migration(query.column_int64(1)); |
| + std::string progress_blob; |
| + progress_marker.SerializeToString(&progress_blob); |
| + |
| + SQLStatement update; |
| + update.prepare(load_dbhandle_, "INSERT INTO models (model_id, " |
| + "progress_marker, initial_sync_ended) VALUES (?, ?, ?)"); |
| + update.bind_blob(0, query.column_blob(0), query.column_bytes(0)); |
| + update.bind_blob(1, progress_blob.data(), progress_blob.length()); |
| + update.bind_bool(2, query.column_bool(2)); |
| + if (SQLITE_DONE != update.step()) |
| + return false; |
| + } |
| + } |
| + // Drop the old table. |
| + SafeDropTable("temp_models"); |
| + |
| + SetVersion(75); |
| + return true; |
| +} |
| int DirectoryBackingStore::CreateTables() { |
| VLOG(1) << "First run, creating tables"; |
| @@ -1106,14 +1180,26 @@ int DirectoryBackingStore::CreateMetasTable(bool is_temporary) { |
| return ExecQuery(load_dbhandle_, query.c_str()); |
| } |
| +int DirectoryBackingStore::CreateV71ModelsTable() { |
| + // This is an old schema for the Models table, used from versions 71 to 74. |
| + return ExecQuery(load_dbhandle_, |
| + "CREATE TABLE models (" |
| + "model_id BLOB primary key, " |
| + "last_download_timestamp INT, " |
| + // Gets set if the syncer ever gets updates from the |
| + // server and the server returns 0. Lets us detect the |
| + // end of the initial sync. |
| + "initial_sync_ended BOOLEAN default 0)"); |
| +} |
| + |
| int DirectoryBackingStore::CreateModelsTable() { |
| - // This is the current schema for the Models table, from version 71 |
| + // This is the current schema for the Models table, from version 75 |
| // onward. If you change the schema, you'll probably want to double-check |
| - // the use of this function in the v70-v71 migration. |
| + // the use of this function in the v74-v75 migration. |
| return ExecQuery(load_dbhandle_, |
| "CREATE TABLE models (" |
| "model_id BLOB primary key, " |
| - "last_download_timestamp INT, " |
| + "progress_marker BLOB, " |
| // Gets set if the syncer ever gets updates from the |
| // server and the server returns 0. Lets us detect the |
| // end of the initial sync. |
| @@ -1124,9 +1210,8 @@ int DirectoryBackingStore::CreateShareInfoTable(bool is_temporary) { |
| const char* name = is_temporary ? "temp_share_info" : "share_info"; |
| string query = "CREATE TABLE "; |
| query.append(name); |
| - // This is the current schema for the ShareInfo table, from version 71 |
| - // onward. If you change the schema, you'll probably want to double-check |
| - // the use of this function in the v70-v71 migration. |
| + // This is the current schema for the ShareInfo table, from version 74 |
| + // onward. |
| query.append(" (" |
| "id TEXT primary key, " |
| "name TEXT, " |
| @@ -1151,9 +1236,7 @@ int DirectoryBackingStore::CreateShareInfoTableVersion71( |
| const char* name = is_temporary ? "temp_share_info" : "share_info"; |
| string query = "CREATE TABLE "; |
| query.append(name); |
| - // This is the current schema for the ShareInfo table, from version 71 |
| - // onward. If you change the schema, you'll probably want to double-check |
| - // the use of this function in the v70-v71 migration. |
| + // This is the schema for the ShareInfo table used from versions 71 to 72. |
| query.append(" (" |
| "id TEXT primary key, " |
| "name TEXT, " |