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

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

Issue 6104003: sync: use progress markers instead of timestamps during GetUpdates (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: For review Created 9 years, 11 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) 2010 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2010 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 "chrome/browser/sync/syncable/directory_backing_store.h" 5 #include "chrome/browser/sync/syncable/directory_backing_store.h"
6 6
7 #include "build/build_config.h" 7 #include "build/build_config.h"
8 8
9 #if defined(OS_MACOSX) 9 #if defined(OS_MACOSX)
10 #include <CoreFoundation/CoreFoundation.h> 10 #include <CoreFoundation/CoreFoundation.h>
(...skipping 26 matching lines...) Expand all
37 using std::string; 37 using std::string;
38 38
39 namespace syncable { 39 namespace syncable {
40 40
41 // This just has to be big enough to hold an UPDATE or INSERT statement that 41 // This just has to be big enough to hold an UPDATE or INSERT statement that
42 // modifies all the columns in the entry table. 42 // modifies all the columns in the entry table.
43 static const string::size_type kUpdateStatementBufferSize = 2048; 43 static const string::size_type kUpdateStatementBufferSize = 2048;
44 44
45 // Increment this version whenever updating DB tables. 45 // Increment this version whenever updating DB tables.
46 extern const int32 kCurrentDBVersion; // Global visibility for our unittest. 46 extern const int32 kCurrentDBVersion; // Global visibility for our unittest.
47 const int32 kCurrentDBVersion = 74; 47 const int32 kCurrentDBVersion = 75;
48 48
49 namespace { 49 namespace {
50 50
51 int ExecQuery(sqlite3* dbhandle, const char* query) { 51 int ExecQuery(sqlite3* dbhandle, const char* query) {
52 SQLStatement statement; 52 SQLStatement statement;
53 int result = statement.prepare(dbhandle, query); 53 int result = statement.prepare(dbhandle, query);
54 if (SQLITE_OK != result) 54 if (SQLITE_OK != result)
55 return result; 55 return result;
56 do { 56 do {
57 result = statement.step(); 57 result = statement.step();
(...skipping 346 matching lines...) Expand 10 before | Expand all | Expand 10 after
404 404
405 if (!(SQLITE_DONE == update.step() && 405 if (!(SQLITE_DONE == update.step() &&
406 SQLITE_OK == update.reset() && 406 SQLITE_OK == update.reset() &&
407 1 == update.changes())) { 407 1 == update.changes())) {
408 return false; 408 return false;
409 } 409 }
410 410
411 for (int i = FIRST_REAL_MODEL_TYPE; i < MODEL_TYPE_COUNT; ++i) { 411 for (int i = FIRST_REAL_MODEL_TYPE; i < MODEL_TYPE_COUNT; ++i) {
412 SQLStatement op; 412 SQLStatement op;
413 op.prepare(dbhandle, "INSERT OR REPLACE INTO models (model_id, " 413 op.prepare(dbhandle, "INSERT OR REPLACE INTO models (model_id, "
414 "last_download_timestamp, initial_sync_ended) VALUES ( ?, ?, ?)"); 414 "progress_marker, initial_sync_ended) VALUES ( ?, ?, ?)");
415 // We persist not ModelType but rather a protobuf-derived ID. 415 // We persist not ModelType but rather a protobuf-derived ID.
416 string model_id = ModelTypeEnumToModelId(ModelTypeFromInt(i)); 416 string model_id = ModelTypeEnumToModelId(ModelTypeFromInt(i));
417 string progress_marker;
418 info.download_progress[i].SerializeToString(&progress_marker);
417 op.bind_blob(0, model_id.data(), model_id.length()); 419 op.bind_blob(0, model_id.data(), model_id.length());
418 op.bind_int64(1, info.last_download_timestamp[i]); 420 op.bind_blob(1, progress_marker.data(), progress_marker.length());
419 op.bind_bool(2, info.initial_sync_ended[i]); 421 op.bind_bool(2, info.initial_sync_ended[i]);
420 422
421 if (!(SQLITE_DONE == op.step() && 423 if (!(SQLITE_DONE == op.step() &&
422 SQLITE_OK == op.reset() && 424 SQLITE_OK == op.reset() &&
423 1 == op.changes())) { 425 1 == op.changes())) {
424 return false; 426 return false;
425 } 427 }
426 } 428 }
427 } 429 }
428 430
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
466 if (MigrateVersion71To72()) 468 if (MigrateVersion71To72())
467 version_on_disk = 72; 469 version_on_disk = 72;
468 } 470 }
469 471
470 // Version 73 added a field for notification state. 472 // Version 73 added a field for notification state.
471 if (version_on_disk == 72) { 473 if (version_on_disk == 72) {
472 if (MigrateVersion72To73()) 474 if (MigrateVersion72To73())
473 version_on_disk = 73; 475 version_on_disk = 73;
474 } 476 }
475 477
478 // Version 74 added state for the autofill migration.
476 if (version_on_disk == 73) { 479 if (version_on_disk == 73) {
477 if (MigrateVersion73To74()) 480 if (MigrateVersion73To74())
478 version_on_disk = 74; 481 version_on_disk = 74;
479 } 482 }
480 483
484 // Version 75 migrated from int64-based timestamps to per-datatype tokens.
485 if (version_on_disk == 74) {
486 if (MigrateVersion74To75())
487 version_on_disk = 75;
488 }
489
481 // If one of the migrations requested it, drop columns that aren't current. 490 // If one of the migrations requested it, drop columns that aren't current.
482 // It's only safe to do this after migrating all the way to the current 491 // It's only safe to do this after migrating all the way to the current
483 // version. 492 // version.
484 if (version_on_disk == kCurrentDBVersion && needs_column_refresh_) { 493 if (version_on_disk == kCurrentDBVersion && needs_column_refresh_) {
485 if (!RefreshColumns()) 494 if (!RefreshColumns())
486 version_on_disk = 0; 495 version_on_disk = 0;
487 } 496 }
488 497
489 // A final, alternative catch-all migration to simply re-sync everything. 498 // A final, alternative catch-all migration to simply re-sync everything.
490 if (version_on_disk != kCurrentDBVersion) { 499 if (version_on_disk != kCurrentDBVersion) {
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after
599 debug_info.autofill_migration_time = 608 debug_info.autofill_migration_time =
600 query.column_int64(6); 609 query.column_int64(6);
601 debug_info.autofill_entries_added_during_migration = 610 debug_info.autofill_entries_added_during_migration =
602 query.column_int(7); 611 query.column_int(7);
603 debug_info.autofill_profile_added_during_migration = 612 debug_info.autofill_profile_added_during_migration =
604 query.column_int(8); 613 query.column_int(8);
605 } 614 }
606 { 615 {
607 SQLStatement query; 616 SQLStatement query;
608 query.prepare(load_dbhandle_, 617 query.prepare(load_dbhandle_,
609 "SELECT model_id, last_download_timestamp, initial_sync_ended " 618 "SELECT model_id, progress_marker, initial_sync_ended "
610 "FROM models"); 619 "FROM models");
611 while (SQLITE_ROW == query.step()) { 620 while (SQLITE_ROW == query.step()) {
612 string model_id; 621 ModelType type = ModelIdToModelTypeEnum(query.column_blob(0),
613 query.column_blob_as_string(0, &model_id); 622 query.column_bytes(0));
614 ModelType type = ModelIdToModelTypeEnum(model_id);
615 if (type != UNSPECIFIED) { 623 if (type != UNSPECIFIED) {
616 info->kernel_info.last_download_timestamp[type] = query.column_int64(1); 624 info->kernel_info.download_progress[type].ParseFromArray(
625 query.column_blob(1), query.column_bytes(1));
617 info->kernel_info.initial_sync_ended[type] = query.column_bool(2); 626 info->kernel_info.initial_sync_ended[type] = query.column_bool(2);
618 } 627 }
619 } 628 }
620 } 629 }
621 { 630 {
622 SQLStatement query; 631 SQLStatement query;
623 query.prepare(load_dbhandle_, 632 query.prepare(load_dbhandle_,
624 "SELECT MAX(metahandle) FROM metas"); 633 "SELECT MAX(metahandle) FROM metas");
625 if (SQLITE_ROW != query.step()) 634 if (SQLITE_ROW != query.step())
626 return false; 635 return false;
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
702 } 711 }
703 712
704 void DirectoryBackingStore::DropAllTables() { 713 void DirectoryBackingStore::DropAllTables() {
705 SafeDropTable("metas"); 714 SafeDropTable("metas");
706 SafeDropTable("temp_metas"); 715 SafeDropTable("temp_metas");
707 SafeDropTable("share_info"); 716 SafeDropTable("share_info");
708 SafeDropTable("temp_share_info"); 717 SafeDropTable("temp_share_info");
709 SafeDropTable("share_version"); 718 SafeDropTable("share_version");
710 SafeDropTable("extended_attributes"); 719 SafeDropTable("extended_attributes");
711 SafeDropTable("models"); 720 SafeDropTable("models");
721 SafeDropTable("temp_models");
712 needs_column_refresh_ = false; 722 needs_column_refresh_ = false;
713 } 723 }
714 724
715 // static 725 // static
716 ModelType DirectoryBackingStore::ModelIdToModelTypeEnum( 726 ModelType DirectoryBackingStore::ModelIdToModelTypeEnum(
717 const string& model_id) { 727 const void* data, int size) {
718 sync_pb::EntitySpecifics specifics; 728 sync_pb::EntitySpecifics specifics;
719 if (!specifics.ParseFromString(model_id)) 729 if (!specifics.ParseFromArray(data, size))
720 return syncable::UNSPECIFIED; 730 return syncable::UNSPECIFIED;
721 return syncable::GetModelTypeFromSpecifics(specifics); 731 return syncable::GetModelTypeFromSpecifics(specifics);
722 } 732 }
723 733
724 // static 734 // static
725 string DirectoryBackingStore::ModelTypeEnumToModelId(ModelType model_type) { 735 string DirectoryBackingStore::ModelTypeEnumToModelId(ModelType model_type) {
726 sync_pb::EntitySpecifics specifics; 736 sync_pb::EntitySpecifics specifics;
727 syncable::AddDefaultExtensionValue(model_type, &specifics); 737 syncable::AddDefaultExtensionValue(model_type, &specifics);
728 return specifics.SerializeAsString(); 738 return specifics.SerializeAsString();
729 } 739 }
(...skipping 163 matching lines...) Expand 10 before | Expand all | Expand 10 after
893 903
894 SetVersion(69); 904 SetVersion(69);
895 needs_column_refresh_ = true; // Trigger deletion of old columns. 905 needs_column_refresh_ = true; // Trigger deletion of old columns.
896 return true; 906 return true;
897 } 907 }
898 908
899 // Version 71, the columns 'initial_sync_ended' and 'last_sync_timestamp' 909 // Version 71, the columns 'initial_sync_ended' and 'last_sync_timestamp'
900 // were removed from the share_info table. They were replaced by 910 // were removed from the share_info table. They were replaced by
901 // the 'models' table, which has these values on a per-datatype basis. 911 // the 'models' table, which has these values on a per-datatype basis.
902 bool DirectoryBackingStore::MigrateVersion70To71() { 912 bool DirectoryBackingStore::MigrateVersion70To71() {
903 if (SQLITE_DONE != CreateModelsTable()) 913 if (SQLITE_DONE != CreateV71ModelsTable())
904 return false; 914 return false;
905 915
906 // Move data from the old share_info columns to the new models table. 916 // Move data from the old share_info columns to the new models table.
907 { 917 {
908 SQLStatement fetch; 918 SQLStatement fetch;
909 fetch.prepare(load_dbhandle_, 919 fetch.prepare(load_dbhandle_,
910 "SELECT last_sync_timestamp, initial_sync_ended FROM share_info"); 920 "SELECT last_sync_timestamp, initial_sync_ended FROM share_info");
911 921
912 if (SQLITE_ROW != fetch.step()) 922 if (SQLITE_ROW != fetch.step())
913 return false; 923 return false;
(...skipping 29 matching lines...) Expand all
943 SafeDropTable("share_info"); 953 SafeDropTable("share_info");
944 result = ExecQuery(load_dbhandle_, 954 result = ExecQuery(load_dbhandle_,
945 "ALTER TABLE temp_share_info RENAME TO share_info"); 955 "ALTER TABLE temp_share_info RENAME TO share_info");
946 if (result != SQLITE_DONE) 956 if (result != SQLITE_DONE)
947 return false; 957 return false;
948 SetVersion(71); 958 SetVersion(71);
949 return true; 959 return true;
950 } 960 }
951 961
952 bool DirectoryBackingStore::MigrateVersion71To72() { 962 bool DirectoryBackingStore::MigrateVersion71To72() {
963 // Version 72 removed a table 'extended_attributes', whose
964 // contents didn't matter.
953 SafeDropTable("extended_attributes"); 965 SafeDropTable("extended_attributes");
954 SetVersion(72); 966 SetVersion(72);
955 return true; 967 return true;
956 } 968 }
957 969
958 bool DirectoryBackingStore::MigrateVersion72To73() { 970 bool DirectoryBackingStore::MigrateVersion72To73() {
971 // Version 73 added one column to the table 'share_info': notification_state
959 int result = 972 int result =
960 ExecQuery(load_dbhandle_, 973 ExecQuery(load_dbhandle_,
961 "ALTER TABLE share_info ADD COLUMN notification_state BLOB"); 974 "ALTER TABLE share_info ADD COLUMN notification_state BLOB");
962 if (result != SQLITE_DONE) 975 if (result != SQLITE_DONE)
963 return false; 976 return false;
964 SetVersion(73); 977 SetVersion(73);
965 return true; 978 return true;
966 } 979 }
967 980
968 bool DirectoryBackingStore::MigrateVersion73To74() { 981 bool DirectoryBackingStore::MigrateVersion73To74() {
982 // Version 74 added the following columns to the table 'share_info':
983 // autofill_migration_state
984 // bookmarks_added_during_autofill_migration
985 // autofill_migration_time
986 // autofill_entries_added_during_migration
987 // autofill_profiles_added_during_migration
988
969 int result = 989 int result =
970 ExecQuery(load_dbhandle_, 990 ExecQuery(load_dbhandle_,
971 "ALTER TABLE share_info ADD COLUMN autofill_migration_state " 991 "ALTER TABLE share_info ADD COLUMN autofill_migration_state "
972 "INT default 0"); 992 "INT default 0");
973 if (result != SQLITE_DONE) 993 if (result != SQLITE_DONE)
974 return false; 994 return false;
975 995
976 result = ExecQuery(load_dbhandle_, 996 result = ExecQuery(load_dbhandle_,
977 "ALTER TABLE share_info ADD COLUMN " 997 "ALTER TABLE share_info ADD COLUMN "
978 "bookmarks_added_during_autofill_migration " 998 "bookmarks_added_during_autofill_migration "
(...skipping 22 matching lines...) Expand all
1001 "autofill_profiles_added_during_migration " 1021 "autofill_profiles_added_during_migration "
1002 "INT default 0"); 1022 "INT default 0");
1003 1023
1004 if (result != SQLITE_DONE) 1024 if (result != SQLITE_DONE)
1005 return false; 1025 return false;
1006 1026
1007 SetVersion(74); 1027 SetVersion(74);
1008 return true; 1028 return true;
1009 } 1029 }
1010 1030
1031 bool DirectoryBackingStore::MigrateVersion74To75() {
1032 // In version 74, there was a table 'models':
1033 // blob model_id (entity specifics, primary key)
1034 // int last_download_timestamp
1035 // boolean initial_sync_ended
1036 // In version 75, we deprecated the integer-valued last_download_timestamp,
1037 // using insted a protobuf-valued progress_marker field:
1038 // blob progress_marker
1039 // The progress_marker values are initialized from the value of
1040 // last_download_timestamp, thereby preserving the download state.
1041
1042 // Move aside the old table and create a new empty one at the current schema.
1043 if (SQLITE_DONE != ExecQuery(load_dbhandle_,
1044 "ALTER TABLE models RENAME TO temp_models")) {
1045 return false;
1046 }
1047 if (!CreateModelsTable())
1048 return false;
1049
1050 SQLStatement query;
1051 query.prepare(load_dbhandle_,
1052 "SELECT model_id, last_download_timestamp, initial_sync_ended "
1053 "FROM temp_models");
1054 while (SQLITE_ROW == query.step()) {
1055 ModelType type = ModelIdToModelTypeEnum(query.column_blob(0),
1056 query.column_bytes(0));
1057 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
1058 // Set the |timestamp_token_for_migration| on a new
1059 // DataTypeProgressMarker, using the old value of last_download_timestamp.
1060 // The server will turn this into a real token on our behalf the next
1061 // time we check for updates.
1062 sync_pb::DataTypeProgressMarker progress_marker;
1063 progress_marker.set_data_type_id(
1064 GetExtensionFieldNumberFromModelType(type));
1065 progress_marker.set_timestamp_token_for_migration(query.column_int64(1));
1066 std::string progress_blob;
1067 progress_marker.SerializeToString(&progress_blob);
1068
1069 SQLStatement update;
1070 update.prepare(load_dbhandle_, "INSERT INTO models (model_id, "
1071 "progress_marker, initial_sync_ended) VALUES (?, ?, ?)");
1072 update.bind_blob(0, query.column_blob(0), query.column_bytes(0));
1073 update.bind_blob(1, progress_blob.data(), progress_blob.length());
1074 update.bind_bool(2, query.column_bool(2));
1075 if (SQLITE_DONE != update.step())
1076 return false;
1077 }
1078 }
1079 // Drop the old table.
1080 SafeDropTable("temp_models");
1081
1082 SetVersion(75);
1083 return true;
1084 }
1011 1085
1012 int DirectoryBackingStore::CreateTables() { 1086 int DirectoryBackingStore::CreateTables() {
1013 VLOG(1) << "First run, creating tables"; 1087 VLOG(1) << "First run, creating tables";
1014 // Create two little tables share_version and share_info 1088 // Create two little tables share_version and share_info
1015 int result = ExecQuery(load_dbhandle_, 1089 int result = ExecQuery(load_dbhandle_,
1016 "CREATE TABLE share_version (" 1090 "CREATE TABLE share_version ("
1017 "id VARCHAR(128) primary key, data INT)"); 1091 "id VARCHAR(128) primary key, data INT)");
1018 if (result != SQLITE_DONE) 1092 if (result != SQLITE_DONE)
1019 return result; 1093 return result;
1020 { 1094 {
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after
1099 } 1173 }
1100 1174
1101 int DirectoryBackingStore::CreateMetasTable(bool is_temporary) { 1175 int DirectoryBackingStore::CreateMetasTable(bool is_temporary) {
1102 const char* name = is_temporary ? "temp_metas" : "metas"; 1176 const char* name = is_temporary ? "temp_metas" : "metas";
1103 string query = "CREATE TABLE "; 1177 string query = "CREATE TABLE ";
1104 query.append(name); 1178 query.append(name);
1105 query.append(ComposeCreateTableColumnSpecs()); 1179 query.append(ComposeCreateTableColumnSpecs());
1106 return ExecQuery(load_dbhandle_, query.c_str()); 1180 return ExecQuery(load_dbhandle_, query.c_str());
1107 } 1181 }
1108 1182
1109 int DirectoryBackingStore::CreateModelsTable() { 1183 int DirectoryBackingStore::CreateV71ModelsTable() {
1110 // This is the current schema for the Models table, from version 71 1184 // This is an old schema for the Models table, used from versions 71 to 74.
1111 // onward. If you change the schema, you'll probably want to double-check
1112 // the use of this function in the v70-v71 migration.
1113 return ExecQuery(load_dbhandle_, 1185 return ExecQuery(load_dbhandle_,
1114 "CREATE TABLE models (" 1186 "CREATE TABLE models ("
1115 "model_id BLOB primary key, " 1187 "model_id BLOB primary key, "
1116 "last_download_timestamp INT, " 1188 "last_download_timestamp INT, "
1117 // Gets set if the syncer ever gets updates from the 1189 // Gets set if the syncer ever gets updates from the
1118 // server and the server returns 0. Lets us detect the 1190 // server and the server returns 0. Lets us detect the
1119 // end of the initial sync. 1191 // end of the initial sync.
1192 "initial_sync_ended BOOLEAN default 0)");
1193 }
1194
1195 int DirectoryBackingStore::CreateModelsTable() {
1196 // This is the current schema for the Models table, from version 75
1197 // onward. If you change the schema, you'll probably want to double-check
1198 // the use of this function in the v74-v75 migration.
1199 return ExecQuery(load_dbhandle_,
1200 "CREATE TABLE models ("
1201 "model_id BLOB primary key, "
1202 "progress_marker BLOB, "
1203 // Gets set if the syncer ever gets updates from the
1204 // server and the server returns 0. Lets us detect the
1205 // end of the initial sync.
1120 "initial_sync_ended BOOLEAN default 0)"); 1206 "initial_sync_ended BOOLEAN default 0)");
1121 } 1207 }
1122 1208
1123 int DirectoryBackingStore::CreateShareInfoTable(bool is_temporary) { 1209 int DirectoryBackingStore::CreateShareInfoTable(bool is_temporary) {
1124 const char* name = is_temporary ? "temp_share_info" : "share_info"; 1210 const char* name = is_temporary ? "temp_share_info" : "share_info";
1125 string query = "CREATE TABLE "; 1211 string query = "CREATE TABLE ";
1126 query.append(name); 1212 query.append(name);
1127 // This is the current schema for the ShareInfo table, from version 71 1213 // This is the current schema for the ShareInfo table, from version 74
1128 // onward. If you change the schema, you'll probably want to double-check 1214 // onward.
1129 // the use of this function in the v70-v71 migration.
1130 query.append(" (" 1215 query.append(" ("
1131 "id TEXT primary key, " 1216 "id TEXT primary key, "
1132 "name TEXT, " 1217 "name TEXT, "
1133 "store_birthday TEXT, " 1218 "store_birthday TEXT, "
1134 "db_create_version TEXT, " 1219 "db_create_version TEXT, "
1135 "db_create_time INT, " 1220 "db_create_time INT, "
1136 "next_id INT default -2, " 1221 "next_id INT default -2, "
1137 "cache_guid TEXT, " 1222 "cache_guid TEXT, "
1138 "autofill_migration_state INT default 0, " 1223 "autofill_migration_state INT default 0, "
1139 "bookmarks_added_during_autofill_migration INT default 0, " 1224 "bookmarks_added_during_autofill_migration INT default 0, "
1140 "autofill_migration_time INT default 0, " 1225 "autofill_migration_time INT default 0, "
1141 "autofill_entries_added_during_migration INT default 0, " 1226 "autofill_entries_added_during_migration INT default 0, "
1142 "autofill_profiles_added_during_migration INT default 0 "); 1227 "autofill_profiles_added_during_migration INT default 0 ");
1143 1228
1144 query.append(", notification_state BLOB"); 1229 query.append(", notification_state BLOB");
1145 query.append(")"); 1230 query.append(")");
1146 return ExecQuery(load_dbhandle_, query.c_str()); 1231 return ExecQuery(load_dbhandle_, query.c_str());
1147 } 1232 }
1148 1233
1149 int DirectoryBackingStore::CreateShareInfoTableVersion71( 1234 int DirectoryBackingStore::CreateShareInfoTableVersion71(
1150 bool is_temporary) { 1235 bool is_temporary) {
1151 const char* name = is_temporary ? "temp_share_info" : "share_info"; 1236 const char* name = is_temporary ? "temp_share_info" : "share_info";
1152 string query = "CREATE TABLE "; 1237 string query = "CREATE TABLE ";
1153 query.append(name); 1238 query.append(name);
1154 // This is the current schema for the ShareInfo table, from version 71 1239 // This is the schema for the ShareInfo table used from versions 71 to 72.
1155 // onward. If you change the schema, you'll probably want to double-check
1156 // the use of this function in the v70-v71 migration.
1157 query.append(" (" 1240 query.append(" ("
1158 "id TEXT primary key, " 1241 "id TEXT primary key, "
1159 "name TEXT, " 1242 "name TEXT, "
1160 "store_birthday TEXT, " 1243 "store_birthday TEXT, "
1161 "db_create_version TEXT, " 1244 "db_create_version TEXT, "
1162 "db_create_time INT, " 1245 "db_create_time INT, "
1163 "next_id INT default -2, " 1246 "next_id INT default -2, "
1164 "cache_guid TEXT )"); 1247 "cache_guid TEXT )");
1165 return ExecQuery(load_dbhandle_, query.c_str()); 1248 return ExecQuery(load_dbhandle_, query.c_str());
1166 } 1249 }
1167 } // namespace syncable 1250 } // namespace syncable
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698