OLD | NEW |
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
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 = 76; | 47 const int32 kCurrentDBVersion = 76; |
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 sqlite_utils::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(); |
58 } while (SQLITE_ROW == result); | 58 } while (SQLITE_ROW == result); |
59 | 59 |
60 return result; | 60 return result; |
61 } | 61 } |
62 | 62 |
63 string GenerateCacheGUID() { | 63 string GenerateCacheGUID() { |
64 return Generate128BitRandomBase64String(); | 64 return Generate128BitRandomBase64String(); |
65 } | 65 } |
66 | 66 |
67 } // namespace | 67 } // namespace |
68 | 68 |
69 | 69 |
70 // Iterate over the fields of |entry| and bind each to |statement| for | 70 // Iterate over the fields of |entry| and bind each to |statement| for |
71 // updating. Returns the number of args bound. | 71 // updating. Returns the number of args bound. |
72 int BindFields(const EntryKernel& entry, SQLStatement* statement) { | 72 int BindFields(const EntryKernel& entry, |
| 73 sqlite_utils::SQLStatement* statement) { |
73 int index = 0; | 74 int index = 0; |
74 int i = 0; | 75 int i = 0; |
75 for (i = BEGIN_FIELDS; i < INT64_FIELDS_END; ++i) { | 76 for (i = BEGIN_FIELDS; i < INT64_FIELDS_END; ++i) { |
76 statement->bind_int64(index++, entry.ref(static_cast<Int64Field>(i))); | 77 statement->bind_int64(index++, entry.ref(static_cast<Int64Field>(i))); |
77 } | 78 } |
78 for ( ; i < ID_FIELDS_END; ++i) { | 79 for ( ; i < ID_FIELDS_END; ++i) { |
79 statement->bind_string(index++, entry.ref(static_cast<IdField>(i)).s_); | 80 statement->bind_string(index++, entry.ref(static_cast<IdField>(i)).s_); |
80 } | 81 } |
81 for ( ; i < BIT_FIELDS_END; ++i) { | 82 for ( ; i < BIT_FIELDS_END; ++i) { |
82 statement->bind_int(index++, entry.ref(static_cast<BitField>(i))); | 83 statement->bind_int(index++, entry.ref(static_cast<BitField>(i))); |
83 } | 84 } |
84 for ( ; i < STRING_FIELDS_END; ++i) { | 85 for ( ; i < STRING_FIELDS_END; ++i) { |
85 statement->bind_string(index++, entry.ref(static_cast<StringField>(i))); | 86 statement->bind_string(index++, entry.ref(static_cast<StringField>(i))); |
86 } | 87 } |
87 std::string temp; | 88 std::string temp; |
88 for ( ; i < PROTO_FIELDS_END; ++i) { | 89 for ( ; i < PROTO_FIELDS_END; ++i) { |
89 entry.ref(static_cast<ProtoField>(i)).SerializeToString(&temp); | 90 entry.ref(static_cast<ProtoField>(i)).SerializeToString(&temp); |
90 statement->bind_blob(index++, temp.data(), temp.length()); | 91 statement->bind_blob(index++, temp.data(), temp.length()); |
91 } | 92 } |
92 return index; | 93 return index; |
93 } | 94 } |
94 | 95 |
95 // The caller owns the returned EntryKernel*. | 96 // The caller owns the returned EntryKernel*. |
96 int UnpackEntry(SQLStatement* statement, EntryKernel** kernel) { | 97 int UnpackEntry(sqlite_utils::SQLStatement* statement, EntryKernel** kernel) { |
97 *kernel = NULL; | 98 *kernel = NULL; |
98 int query_result = statement->step(); | 99 int query_result = statement->step(); |
99 if (SQLITE_ROW == query_result) { | 100 if (SQLITE_ROW == query_result) { |
100 *kernel = new EntryKernel; | 101 *kernel = new EntryKernel; |
101 (*kernel)->clear_dirty(NULL); | 102 (*kernel)->clear_dirty(NULL); |
102 DCHECK(statement->column_count() == static_cast<int>(FIELD_COUNT)); | 103 DCHECK(statement->column_count() == static_cast<int>(FIELD_COUNT)); |
103 int i = 0; | 104 int i = 0; |
104 for (i = BEGIN_FIELDS; i < INT64_FIELDS_END; ++i) { | 105 for (i = BEGIN_FIELDS; i < INT64_FIELDS_END; ++i) { |
105 (*kernel)->put(static_cast<Int64Field>(i), statement->column_int64(i)); | 106 (*kernel)->put(static_cast<Int64Field>(i), statement->column_int64(i)); |
106 } | 107 } |
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
188 sqlite3_busy_timeout(scoped_handle.get(), std::numeric_limits<int>::max()); | 189 sqlite3_busy_timeout(scoped_handle.get(), std::numeric_limits<int>::max()); |
189 { | 190 { |
190 string integrity_error; | 191 string integrity_error; |
191 bool is_ok = CheckIntegrity(scoped_handle.get(), &integrity_error); | 192 bool is_ok = CheckIntegrity(scoped_handle.get(), &integrity_error); |
192 if (!is_ok) { | 193 if (!is_ok) { |
193 LOG(ERROR) << "Integrity check failed: " << integrity_error; | 194 LOG(ERROR) << "Integrity check failed: " << integrity_error; |
194 return false; | 195 return false; |
195 } | 196 } |
196 } | 197 } |
197 { | 198 { |
198 SQLStatement statement; | 199 sqlite_utils::SQLStatement statement; |
199 statement.prepare(scoped_handle.get(), "PRAGMA fullfsync = 1"); | 200 statement.prepare(scoped_handle.get(), "PRAGMA fullfsync = 1"); |
200 if (SQLITE_DONE != statement.step()) { | 201 if (SQLITE_DONE != statement.step()) { |
201 LOG(ERROR) << sqlite3_errmsg(scoped_handle.get()); | 202 LOG(ERROR) << sqlite3_errmsg(scoped_handle.get()); |
202 return false; | 203 return false; |
203 } | 204 } |
204 } | 205 } |
205 { | 206 { |
206 SQLStatement statement; | 207 sqlite_utils::SQLStatement statement; |
207 statement.prepare(scoped_handle.get(), "PRAGMA synchronous = 2"); | 208 statement.prepare(scoped_handle.get(), "PRAGMA synchronous = 2"); |
208 if (SQLITE_DONE != statement.step()) { | 209 if (SQLITE_DONE != statement.step()) { |
209 LOG(ERROR) << sqlite3_errmsg(scoped_handle.get()); | 210 LOG(ERROR) << sqlite3_errmsg(scoped_handle.get()); |
210 return false; | 211 return false; |
211 } | 212 } |
212 } | 213 } |
213 sqlite3_busy_timeout(scoped_handle.release(), | 214 sqlite3_busy_timeout(scoped_handle.release(), |
214 kDirectoryBackingStoreBusyTimeoutMs); | 215 kDirectoryBackingStoreBusyTimeoutMs); |
215 #if defined(OS_WIN) | 216 #if defined(OS_WIN) |
216 // Do not index this file. Scanning can occur every time we close the file, | 217 // Do not index this file. Scanning can occur every time we close the file, |
217 // which causes long delays in SQLite's file locking. | 218 // which causes long delays in SQLite's file locking. |
218 const DWORD attrs = GetFileAttributes(backing_filepath_.value().c_str()); | 219 const DWORD attrs = GetFileAttributes(backing_filepath_.value().c_str()); |
219 const BOOL attrs_set = | 220 const BOOL attrs_set = |
220 SetFileAttributes(backing_filepath_.value().c_str(), | 221 SetFileAttributes(backing_filepath_.value().c_str(), |
221 attrs | FILE_ATTRIBUTE_NOT_CONTENT_INDEXED); | 222 attrs | FILE_ATTRIBUTE_NOT_CONTENT_INDEXED); |
222 #endif | 223 #endif |
223 | 224 |
224 return true; | 225 return true; |
225 } | 226 } |
226 return false; | 227 return false; |
227 } | 228 } |
228 | 229 |
229 bool DirectoryBackingStore::CheckIntegrity(sqlite3* handle, string* error) | 230 bool DirectoryBackingStore::CheckIntegrity(sqlite3* handle, string* error) |
230 const { | 231 const { |
231 SQLStatement statement; | 232 sqlite_utils::SQLStatement statement; |
232 statement.prepare(handle, "PRAGMA integrity_check(1)"); | 233 statement.prepare(handle, "PRAGMA integrity_check(1)"); |
233 if (SQLITE_ROW != statement.step()) { | 234 if (SQLITE_ROW != statement.step()) { |
234 *error = sqlite3_errmsg(handle); | 235 *error = sqlite3_errmsg(handle); |
235 return false; | 236 return false; |
236 } | 237 } |
237 string integrity_result = statement.column_text(0); | 238 string integrity_result = statement.column_text(0); |
238 if (integrity_result != "ok") { | 239 if (integrity_result != "ok") { |
239 *error = integrity_result; | 240 *error = integrity_result; |
240 return false; | 241 return false; |
241 } | 242 } |
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
332 sqlite3* dbhandle = LazyGetSaveHandle(); | 333 sqlite3* dbhandle = LazyGetSaveHandle(); |
333 | 334 |
334 string query = "DELETE FROM metas WHERE metahandle IN ("; | 335 string query = "DELETE FROM metas WHERE metahandle IN ("; |
335 for (MetahandleSet::const_iterator it = handles.begin(); it != handles.end(); | 336 for (MetahandleSet::const_iterator it = handles.begin(); it != handles.end(); |
336 ++it) { | 337 ++it) { |
337 if (it != handles.begin()) | 338 if (it != handles.begin()) |
338 query.append(","); | 339 query.append(","); |
339 query.append(base::Int64ToString(*it)); | 340 query.append(base::Int64ToString(*it)); |
340 } | 341 } |
341 query.append(")"); | 342 query.append(")"); |
342 SQLStatement statement; | 343 sqlite_utils::SQLStatement statement; |
343 int result = statement.prepare(dbhandle, query.data(), query.size()); | 344 int result = statement.prepare(dbhandle, query.data(), query.size()); |
344 if (SQLITE_OK == result) | 345 if (SQLITE_OK == result) |
345 result = statement.step(); | 346 result = statement.step(); |
346 | 347 |
347 return SQLITE_DONE == result; | 348 return SQLITE_DONE == result; |
348 } | 349 } |
349 | 350 |
350 bool DirectoryBackingStore::SaveChanges( | 351 bool DirectoryBackingStore::SaveChanges( |
351 const Directory::SaveChangesSnapshot& snapshot) { | 352 const Directory::SaveChangesSnapshot& snapshot) { |
352 sqlite3* dbhandle = LazyGetSaveHandle(); | 353 sqlite3* dbhandle = LazyGetSaveHandle(); |
353 | 354 |
354 // SQLTransaction::BeginExclusive causes a disk write to occur. This is not | 355 // SQLTransaction::BeginExclusive causes a disk write to occur. This is not |
355 // something that should happen every 10 seconds when this function runs, so | 356 // something that should happen every 10 seconds when this function runs, so |
356 // just stop here if there's nothing to save. | 357 // just stop here if there's nothing to save. |
357 bool save_info = | 358 bool save_info = |
358 (Directory::KERNEL_SHARE_INFO_DIRTY == snapshot.kernel_info_status); | 359 (Directory::KERNEL_SHARE_INFO_DIRTY == snapshot.kernel_info_status); |
359 if (snapshot.dirty_metas.size() < 1 && !save_info) | 360 if (snapshot.dirty_metas.size() < 1 && !save_info) |
360 return true; | 361 return true; |
361 | 362 |
362 SQLTransaction transaction(dbhandle); | 363 sqlite_utils::SQLTransaction transaction(dbhandle); |
363 if (SQLITE_OK != transaction.BeginExclusive()) | 364 if (SQLITE_OK != transaction.BeginExclusive()) |
364 return false; | 365 return false; |
365 | 366 |
366 for (EntryKernelSet::const_iterator i = snapshot.dirty_metas.begin(); | 367 for (EntryKernelSet::const_iterator i = snapshot.dirty_metas.begin(); |
367 i != snapshot.dirty_metas.end(); ++i) { | 368 i != snapshot.dirty_metas.end(); ++i) { |
368 DCHECK(i->is_dirty()); | 369 DCHECK(i->is_dirty()); |
369 if (!SaveEntryToDB(*i)) | 370 if (!SaveEntryToDB(*i)) |
370 return false; | 371 return false; |
371 } | 372 } |
372 | 373 |
373 if (!DeleteEntries(snapshot.metahandles_to_purge)) | 374 if (!DeleteEntries(snapshot.metahandles_to_purge)) |
374 return false; | 375 return false; |
375 | 376 |
376 if (save_info) { | 377 if (save_info) { |
377 const Directory::PersistedKernelInfo& info = snapshot.kernel_info; | 378 const Directory::PersistedKernelInfo& info = snapshot.kernel_info; |
378 SQLStatement update; | 379 sqlite_utils::SQLStatement update; |
379 update.prepare(dbhandle, "UPDATE share_info " | 380 update.prepare(dbhandle, "UPDATE share_info " |
380 "SET store_birthday = ?, " | 381 "SET store_birthday = ?, " |
381 "next_id = ?, " | 382 "next_id = ?, " |
382 "notification_state = ? "); | 383 "notification_state = ? "); |
383 | 384 |
384 update.bind_string(0, info.store_birthday); | 385 update.bind_string(0, info.store_birthday); |
385 update.bind_int64(1, info.next_id); | 386 update.bind_int64(1, info.next_id); |
386 update.bind_blob(2, info.notification_state.data(), | 387 update.bind_blob(2, info.notification_state.data(), |
387 info.notification_state.size()); | 388 info.notification_state.size()); |
388 | 389 |
389 if (!(SQLITE_DONE == update.step() && | 390 if (!(SQLITE_DONE == update.step() && |
390 SQLITE_OK == update.reset() && | 391 SQLITE_OK == update.reset() && |
391 1 == update.changes())) { | 392 1 == update.changes())) { |
392 return false; | 393 return false; |
393 } | 394 } |
394 | 395 |
395 for (int i = FIRST_REAL_MODEL_TYPE; i < MODEL_TYPE_COUNT; ++i) { | 396 for (int i = FIRST_REAL_MODEL_TYPE; i < MODEL_TYPE_COUNT; ++i) { |
396 SQLStatement op; | 397 sqlite_utils::SQLStatement op; |
397 op.prepare(dbhandle, "INSERT OR REPLACE INTO models (model_id, " | 398 op.prepare(dbhandle, "INSERT OR REPLACE INTO models (model_id, " |
398 "progress_marker, initial_sync_ended) VALUES ( ?, ?, ?)"); | 399 "progress_marker, initial_sync_ended) VALUES ( ?, ?, ?)"); |
399 // We persist not ModelType but rather a protobuf-derived ID. | 400 // We persist not ModelType but rather a protobuf-derived ID. |
400 string model_id = ModelTypeEnumToModelId(ModelTypeFromInt(i)); | 401 string model_id = ModelTypeEnumToModelId(ModelTypeFromInt(i)); |
401 string progress_marker; | 402 string progress_marker; |
402 info.download_progress[i].SerializeToString(&progress_marker); | 403 info.download_progress[i].SerializeToString(&progress_marker); |
403 op.bind_blob(0, model_id.data(), model_id.length()); | 404 op.bind_blob(0, model_id.data(), model_id.length()); |
404 op.bind_blob(1, progress_marker.data(), progress_marker.length()); | 405 op.bind_blob(1, progress_marker.data(), progress_marker.length()); |
405 op.bind_bool(2, info.initial_sync_ended[i]); | 406 op.bind_bool(2, info.initial_sync_ended[i]); |
406 | 407 |
407 if (!(SQLITE_DONE == op.step() && | 408 if (!(SQLITE_DONE == op.step() && |
408 SQLITE_OK == op.reset() && | 409 SQLITE_OK == op.reset() && |
409 1 == op.changes())) { | 410 1 == op.changes())) { |
410 return false; | 411 return false; |
411 } | 412 } |
412 } | 413 } |
413 } | 414 } |
414 | 415 |
415 return (SQLITE_OK == transaction.Commit()); | 416 return (SQLITE_OK == transaction.Commit()); |
416 } | 417 } |
417 | 418 |
418 DirOpenResult DirectoryBackingStore::InitializeTables() { | 419 DirOpenResult DirectoryBackingStore::InitializeTables() { |
419 SQLTransaction transaction(load_dbhandle_); | 420 sqlite_utils::SQLTransaction transaction(load_dbhandle_); |
420 if (SQLITE_OK != transaction.BeginExclusive()) { | 421 if (SQLITE_OK != transaction.BeginExclusive()) { |
421 return FAILED_DISK_FULL; | 422 return FAILED_DISK_FULL; |
422 } | 423 } |
423 int version_on_disk = GetVersion(); | 424 int version_on_disk = GetVersion(); |
424 int last_result = SQLITE_DONE; | 425 int last_result = SQLITE_DONE; |
425 | 426 |
426 // Upgrade from version 67. Version 67 was widely distributed as the original | 427 // Upgrade from version 67. Version 67 was widely distributed as the original |
427 // Bookmark Sync release. Version 68 removed unique naming. | 428 // Bookmark Sync release. Version 68 removed unique naming. |
428 if (version_on_disk == 67) { | 429 if (version_on_disk == 67) { |
429 if (MigrateVersion67To68()) | 430 if (MigrateVersion67To68()) |
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
492 return FAILED_NEWER_VERSION; | 493 return FAILED_NEWER_VERSION; |
493 } | 494 } |
494 // Fallback (re-sync everything) migration path. | 495 // Fallback (re-sync everything) migration path. |
495 VLOG(1) << "Old/null sync database, version " << version_on_disk; | 496 VLOG(1) << "Old/null sync database, version " << version_on_disk; |
496 // Delete the existing database (if any), and create a fresh one. | 497 // Delete the existing database (if any), and create a fresh one. |
497 DropAllTables(); | 498 DropAllTables(); |
498 last_result = CreateTables(); | 499 last_result = CreateTables(); |
499 } | 500 } |
500 if (SQLITE_DONE == last_result) { | 501 if (SQLITE_DONE == last_result) { |
501 { | 502 { |
502 SQLStatement statement; | 503 sqlite_utils::SQLStatement statement; |
503 statement.prepare(load_dbhandle_, | 504 statement.prepare(load_dbhandle_, |
504 "SELECT db_create_version, db_create_time FROM share_info"); | 505 "SELECT db_create_version, db_create_time FROM share_info"); |
505 if (SQLITE_ROW != statement.step()) { | 506 if (SQLITE_ROW != statement.step()) { |
506 transaction.Rollback(); | 507 transaction.Rollback(); |
507 return FAILED_DISK_FULL; | 508 return FAILED_DISK_FULL; |
508 } | 509 } |
509 string db_create_version = statement.column_text(0); | 510 string db_create_version = statement.column_text(0); |
510 int db_create_time = statement.column_int(1); | 511 int db_create_time = statement.column_int(1); |
511 statement.reset(); | 512 statement.reset(); |
512 VLOG(1) << "DB created at " << db_create_time << " by version " << | 513 VLOG(1) << "DB created at " << db_create_time << " by version " << |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
571 needs_column_refresh_ = false; | 572 needs_column_refresh_ = false; |
572 return true; | 573 return true; |
573 } | 574 } |
574 | 575 |
575 bool DirectoryBackingStore::LoadEntries(MetahandlesIndex* entry_bucket) { | 576 bool DirectoryBackingStore::LoadEntries(MetahandlesIndex* entry_bucket) { |
576 string select; | 577 string select; |
577 select.reserve(kUpdateStatementBufferSize); | 578 select.reserve(kUpdateStatementBufferSize); |
578 select.append("SELECT "); | 579 select.append("SELECT "); |
579 AppendColumnList(&select); | 580 AppendColumnList(&select); |
580 select.append(" FROM metas "); | 581 select.append(" FROM metas "); |
581 SQLStatement statement; | 582 sqlite_utils::SQLStatement statement; |
582 statement.prepare(load_dbhandle_, select.c_str()); | 583 statement.prepare(load_dbhandle_, select.c_str()); |
583 base::hash_set<int64> handles; | 584 base::hash_set<int64> handles; |
584 EntryKernel* kernel = NULL; | 585 EntryKernel* kernel = NULL; |
585 int query_result; | 586 int query_result; |
586 while (SQLITE_ROW == (query_result = UnpackEntry(&statement, &kernel))) { | 587 while (SQLITE_ROW == (query_result = UnpackEntry(&statement, &kernel))) { |
587 DCHECK(handles.insert(kernel->ref(META_HANDLE)).second); // Only in debug. | 588 DCHECK(handles.insert(kernel->ref(META_HANDLE)).second); // Only in debug. |
588 entry_bucket->insert(kernel); | 589 entry_bucket->insert(kernel); |
589 } | 590 } |
590 return SQLITE_DONE == query_result; | 591 return SQLITE_DONE == query_result; |
591 } | 592 } |
592 | 593 |
593 bool DirectoryBackingStore::LoadInfo(Directory::KernelLoadInfo* info) { | 594 bool DirectoryBackingStore::LoadInfo(Directory::KernelLoadInfo* info) { |
594 { | 595 { |
595 SQLStatement query; | 596 sqlite_utils::SQLStatement query; |
596 query.prepare(load_dbhandle_, | 597 query.prepare(load_dbhandle_, |
597 "SELECT store_birthday, next_id, cache_guid, " | 598 "SELECT store_birthday, next_id, cache_guid, " |
598 "notification_state " | 599 "notification_state " |
599 "FROM share_info"); | 600 "FROM share_info"); |
600 if (SQLITE_ROW != query.step()) | 601 if (SQLITE_ROW != query.step()) |
601 return false; | 602 return false; |
602 info->kernel_info.store_birthday = query.column_string(0); | 603 info->kernel_info.store_birthday = query.column_string(0); |
603 info->kernel_info.next_id = query.column_int64(1); | 604 info->kernel_info.next_id = query.column_int64(1); |
604 info->cache_guid = query.column_string(2); | 605 info->cache_guid = query.column_string(2); |
605 query.column_blob_as_string(3, &info->kernel_info.notification_state); | 606 query.column_blob_as_string(3, &info->kernel_info.notification_state); |
606 } | 607 } |
607 { | 608 { |
608 SQLStatement query; | 609 sqlite_utils::SQLStatement query; |
609 query.prepare(load_dbhandle_, | 610 query.prepare(load_dbhandle_, |
610 "SELECT model_id, progress_marker, initial_sync_ended " | 611 "SELECT model_id, progress_marker, initial_sync_ended " |
611 "FROM models"); | 612 "FROM models"); |
612 while (SQLITE_ROW == query.step()) { | 613 while (SQLITE_ROW == query.step()) { |
613 ModelType type = ModelIdToModelTypeEnum(query.column_blob(0), | 614 ModelType type = ModelIdToModelTypeEnum(query.column_blob(0), |
614 query.column_bytes(0)); | 615 query.column_bytes(0)); |
615 if (type != UNSPECIFIED && type != TOP_LEVEL_FOLDER) { | 616 if (type != UNSPECIFIED && type != TOP_LEVEL_FOLDER) { |
616 info->kernel_info.download_progress[type].ParseFromArray( | 617 info->kernel_info.download_progress[type].ParseFromArray( |
617 query.column_blob(1), query.column_bytes(1)); | 618 query.column_blob(1), query.column_bytes(1)); |
618 info->kernel_info.initial_sync_ended[type] = query.column_bool(2); | 619 info->kernel_info.initial_sync_ended[type] = query.column_bool(2); |
619 } | 620 } |
620 } | 621 } |
621 } | 622 } |
622 { | 623 { |
623 SQLStatement query; | 624 sqlite_utils::SQLStatement query; |
624 query.prepare(load_dbhandle_, | 625 query.prepare(load_dbhandle_, |
625 "SELECT MAX(metahandle) FROM metas"); | 626 "SELECT MAX(metahandle) FROM metas"); |
626 if (SQLITE_ROW != query.step()) | 627 if (SQLITE_ROW != query.step()) |
627 return false; | 628 return false; |
628 info->max_metahandle = query.column_int64(0); | 629 info->max_metahandle = query.column_int64(0); |
629 } | 630 } |
630 return true; | 631 return true; |
631 } | 632 } |
632 | 633 |
633 bool DirectoryBackingStore::SaveEntryToDB(const EntryKernel& entry) { | 634 bool DirectoryBackingStore::SaveEntryToDB(const EntryKernel& entry) { |
(...skipping 10 matching lines...) Expand all Loading... |
644 query.append(separator); | 645 query.append(separator); |
645 values.append(separator); | 646 values.append(separator); |
646 separator = ", "; | 647 separator = ", "; |
647 query.append(ColumnName(i)); | 648 query.append(ColumnName(i)); |
648 values.append("?"); | 649 values.append("?"); |
649 } | 650 } |
650 | 651 |
651 query.append(" ) "); | 652 query.append(" ) "); |
652 values.append(" )"); | 653 values.append(" )"); |
653 query.append(values); | 654 query.append(values); |
654 SQLStatement statement; | 655 sqlite_utils::SQLStatement statement; |
655 statement.prepare(save_dbhandle_, query.c_str()); | 656 statement.prepare(save_dbhandle_, query.c_str()); |
656 BindFields(entry, &statement); | 657 BindFields(entry, &statement); |
657 return (SQLITE_DONE == statement.step() && | 658 return (SQLITE_DONE == statement.step() && |
658 SQLITE_OK == statement.reset() && | 659 SQLITE_OK == statement.reset() && |
659 1 == statement.changes()); | 660 1 == statement.changes()); |
660 } | 661 } |
661 | 662 |
662 bool DirectoryBackingStore::DropDeletedEntries() { | 663 bool DirectoryBackingStore::DropDeletedEntries() { |
663 static const char delete_metas[] = "DELETE FROM metas WHERE metahandle IN " | 664 static const char delete_metas[] = "DELETE FROM metas WHERE metahandle IN " |
664 "(SELECT metahandle from death_row)"; | 665 "(SELECT metahandle from death_row)"; |
665 // Put all statements into a transaction for better performance | 666 // Put all statements into a transaction for better performance |
666 SQLTransaction transaction(load_dbhandle_); | 667 sqlite_utils::SQLTransaction transaction(load_dbhandle_); |
667 transaction.Begin(); | 668 transaction.Begin(); |
668 if (SQLITE_DONE != ExecQuery( | 669 if (SQLITE_DONE != ExecQuery( |
669 load_dbhandle_, | 670 load_dbhandle_, |
670 "CREATE TEMP TABLE death_row (metahandle BIGINT)")) { | 671 "CREATE TEMP TABLE death_row (metahandle BIGINT)")) { |
671 return false; | 672 return false; |
672 } | 673 } |
673 if (SQLITE_DONE != ExecQuery(load_dbhandle_, | 674 if (SQLITE_DONE != ExecQuery(load_dbhandle_, |
674 "INSERT INTO death_row " | 675 "INSERT INTO death_row " |
675 "SELECT metahandle from metas WHERE is_del > 0 " | 676 "SELECT metahandle from metas WHERE is_del > 0 " |
676 " AND is_unsynced < 1" | 677 " AND is_unsynced < 1" |
677 " AND is_unapplied_update < 1")) { | 678 " AND is_unapplied_update < 1")) { |
678 return false; | 679 return false; |
679 } | 680 } |
680 if (SQLITE_DONE != ExecQuery(load_dbhandle_, delete_metas)) { | 681 if (SQLITE_DONE != ExecQuery(load_dbhandle_, delete_metas)) { |
681 return false; | 682 return false; |
682 } | 683 } |
683 if (SQLITE_DONE != ExecQuery(load_dbhandle_, "DROP TABLE death_row")) { | 684 if (SQLITE_DONE != ExecQuery(load_dbhandle_, "DROP TABLE death_row")) { |
684 return false; | 685 return false; |
685 } | 686 } |
686 transaction.Commit(); | 687 transaction.Commit(); |
687 return true; | 688 return true; |
688 } | 689 } |
689 | 690 |
690 int DirectoryBackingStore::SafeDropTable(const char* table_name) { | 691 int DirectoryBackingStore::SafeDropTable(const char* table_name) { |
691 string query = "DROP TABLE IF EXISTS "; | 692 string query = "DROP TABLE IF EXISTS "; |
692 query.append(table_name); | 693 query.append(table_name); |
693 SQLStatement statement; | 694 sqlite_utils::SQLStatement statement; |
694 int result = statement.prepare(load_dbhandle_, query.data(), | 695 int result = statement.prepare(load_dbhandle_, query.data(), |
695 query.size()); | 696 query.size()); |
696 if (SQLITE_OK == result) { | 697 if (SQLITE_OK == result) { |
697 result = statement.step(); | 698 result = statement.step(); |
698 if (SQLITE_DONE == result) | 699 if (SQLITE_DONE == result) |
699 statement.finalize(); | 700 statement.finalize(); |
700 } | 701 } |
701 | 702 |
702 return result; | 703 return result; |
703 } | 704 } |
(...skipping 22 matching lines...) Expand all Loading... |
726 // static | 727 // static |
727 string DirectoryBackingStore::ModelTypeEnumToModelId(ModelType model_type) { | 728 string DirectoryBackingStore::ModelTypeEnumToModelId(ModelType model_type) { |
728 sync_pb::EntitySpecifics specifics; | 729 sync_pb::EntitySpecifics specifics; |
729 syncable::AddDefaultExtensionValue(model_type, &specifics); | 730 syncable::AddDefaultExtensionValue(model_type, &specifics); |
730 return specifics.SerializeAsString(); | 731 return specifics.SerializeAsString(); |
731 } | 732 } |
732 | 733 |
733 bool DirectoryBackingStore::MigrateToSpecifics( | 734 bool DirectoryBackingStore::MigrateToSpecifics( |
734 const char* old_columns, | 735 const char* old_columns, |
735 const char* specifics_column, | 736 const char* specifics_column, |
736 void (*handler_function)(SQLStatement* old_value_query, | 737 void (*handler_function)(sqlite_utils::SQLStatement* old_value_query, |
737 int old_value_column, | 738 int old_value_column, |
738 sync_pb::EntitySpecifics* mutable_new_value)) { | 739 sync_pb::EntitySpecifics* mutable_new_value)) { |
739 std::string query_sql = base::StringPrintf( | 740 std::string query_sql = base::StringPrintf( |
740 "SELECT metahandle, %s, %s FROM metas", specifics_column, old_columns); | 741 "SELECT metahandle, %s, %s FROM metas", specifics_column, old_columns); |
741 std::string update_sql = base::StringPrintf( | 742 std::string update_sql = base::StringPrintf( |
742 "UPDATE metas SET %s = ? WHERE metahandle = ?", specifics_column); | 743 "UPDATE metas SET %s = ? WHERE metahandle = ?", specifics_column); |
743 SQLStatement query; | 744 sqlite_utils::SQLStatement query; |
744 query.prepare(load_dbhandle_, query_sql.c_str()); | 745 query.prepare(load_dbhandle_, query_sql.c_str()); |
745 while (query.step() == SQLITE_ROW) { | 746 while (query.step() == SQLITE_ROW) { |
746 int64 metahandle = query.column_int64(0); | 747 int64 metahandle = query.column_int64(0); |
747 std::string new_value_bytes; | 748 std::string new_value_bytes; |
748 query.column_blob_as_string(1, &new_value_bytes); | 749 query.column_blob_as_string(1, &new_value_bytes); |
749 sync_pb::EntitySpecifics new_value; | 750 sync_pb::EntitySpecifics new_value; |
750 new_value.ParseFromString(new_value_bytes); | 751 new_value.ParseFromString(new_value_bytes); |
751 handler_function(&query, 2, &new_value); | 752 handler_function(&query, 2, &new_value); |
752 new_value.SerializeToString(&new_value_bytes); | 753 new_value.SerializeToString(&new_value_bytes); |
753 | 754 |
754 SQLStatement update; | 755 sqlite_utils::SQLStatement update; |
755 update.prepare(load_dbhandle_, update_sql.data(), update_sql.length()); | 756 update.prepare(load_dbhandle_, update_sql.data(), update_sql.length()); |
756 update.bind_blob(0, new_value_bytes.data(), new_value_bytes.length()); | 757 update.bind_blob(0, new_value_bytes.data(), new_value_bytes.length()); |
757 update.bind_int64(1, metahandle); | 758 update.bind_int64(1, metahandle); |
758 if (update.step() != SQLITE_DONE) { | 759 if (update.step() != SQLITE_DONE) { |
759 NOTREACHED(); | 760 NOTREACHED(); |
760 return false; | 761 return false; |
761 } | 762 } |
762 } | 763 } |
763 return true; | 764 return true; |
764 } | 765 } |
765 | 766 |
766 bool DirectoryBackingStore::AddColumn(const ColumnSpec* column) { | 767 bool DirectoryBackingStore::AddColumn(const ColumnSpec* column) { |
767 SQLStatement add_column; | 768 sqlite_utils::SQLStatement add_column; |
768 std::string sql = base::StringPrintf( | 769 std::string sql = base::StringPrintf( |
769 "ALTER TABLE metas ADD COLUMN %s %s", column->name, column->spec); | 770 "ALTER TABLE metas ADD COLUMN %s %s", column->name, column->spec); |
770 add_column.prepare(load_dbhandle_, sql.c_str()); | 771 add_column.prepare(load_dbhandle_, sql.c_str()); |
771 return add_column.step() == SQLITE_DONE; | 772 return add_column.step() == SQLITE_DONE; |
772 } | 773 } |
773 | 774 |
774 bool DirectoryBackingStore::SetVersion(int version) { | 775 bool DirectoryBackingStore::SetVersion(int version) { |
775 SQLStatement statement; | 776 sqlite_utils::SQLStatement statement; |
776 statement.prepare(load_dbhandle_, "UPDATE share_version SET data = ?"); | 777 statement.prepare(load_dbhandle_, "UPDATE share_version SET data = ?"); |
777 statement.bind_int(0, version); | 778 statement.bind_int(0, version); |
778 return statement.step() == SQLITE_DONE; | 779 return statement.step() == SQLITE_DONE; |
779 } | 780 } |
780 | 781 |
781 int DirectoryBackingStore::GetVersion() { | 782 int DirectoryBackingStore::GetVersion() { |
782 if (!sqlite_utils::DoesSqliteTableExist(load_dbhandle_, "share_version")) | 783 if (!sqlite_utils::DoesSqliteTableExist(load_dbhandle_, "share_version")) |
783 return 0; | 784 return 0; |
784 SQLStatement version_query; | 785 sqlite_utils::SQLStatement version_query; |
785 version_query.prepare(load_dbhandle_, "SELECT data from share_version"); | 786 version_query.prepare(load_dbhandle_, "SELECT data from share_version"); |
786 if (SQLITE_ROW != version_query.step()) | 787 if (SQLITE_ROW != version_query.step()) |
787 return 0; | 788 return 0; |
788 int value = version_query.column_int(0); | 789 int value = version_query.column_int(0); |
789 if (version_query.reset() != SQLITE_OK) | 790 if (version_query.reset() != SQLITE_OK) |
790 return 0; | 791 return 0; |
791 return value; | 792 return value; |
792 } | 793 } |
793 | 794 |
794 bool DirectoryBackingStore::MigrateVersion67To68() { | 795 bool DirectoryBackingStore::MigrateVersion67To68() { |
(...skipping 14 matching lines...) Expand all Loading... |
809 // we rename the column again, we need to inline the old | 810 // we rename the column again, we need to inline the old |
810 // intermediate name / column spec. | 811 // intermediate name / column spec. |
811 if (!AddColumn(&g_metas_columns[UNIQUE_SERVER_TAG])) { | 812 if (!AddColumn(&g_metas_columns[UNIQUE_SERVER_TAG])) { |
812 return false; | 813 return false; |
813 } | 814 } |
814 if (!AddColumn(&g_metas_columns[UNIQUE_CLIENT_TAG])) { | 815 if (!AddColumn(&g_metas_columns[UNIQUE_CLIENT_TAG])) { |
815 return false; | 816 return false; |
816 } | 817 } |
817 needs_column_refresh_ = true; | 818 needs_column_refresh_ = true; |
818 | 819 |
819 SQLStatement statement; | 820 sqlite_utils::SQLStatement statement; |
820 statement.prepare(load_dbhandle_, | 821 statement.prepare(load_dbhandle_, |
821 "UPDATE metas SET unique_server_tag = singleton_tag"); | 822 "UPDATE metas SET unique_server_tag = singleton_tag"); |
822 return statement.step() == SQLITE_DONE; | 823 return statement.step() == SQLITE_DONE; |
823 } | 824 } |
824 | 825 |
825 namespace { | 826 namespace { |
826 | 827 |
827 // Callback passed to MigrateToSpecifics for the v68->v69 migration. See | 828 // Callback passed to MigrateToSpecifics for the v68->v69 migration. See |
828 // MigrateVersion68To69(). | 829 // MigrateVersion68To69(). |
829 void EncodeBookmarkURLAndFavicon(SQLStatement* old_value_query, | 830 void EncodeBookmarkURLAndFavicon(sqlite_utils::SQLStatement* old_value_query, |
830 int old_value_column, | 831 int old_value_column, |
831 sync_pb::EntitySpecifics* mutable_new_value) { | 832 sync_pb::EntitySpecifics* mutable_new_value) { |
832 // Extract data from the column trio we expect. | 833 // Extract data from the column trio we expect. |
833 bool old_is_bookmark_object = old_value_query->column_bool(old_value_column); | 834 bool old_is_bookmark_object = old_value_query->column_bool(old_value_column); |
834 std::string old_url = old_value_query->column_string(old_value_column + 1); | 835 std::string old_url = old_value_query->column_string(old_value_column + 1); |
835 std::string old_favicon; | 836 std::string old_favicon; |
836 old_value_query->column_blob_as_string(old_value_column + 2, &old_favicon); | 837 old_value_query->column_blob_as_string(old_value_column + 2, &old_favicon); |
837 bool old_is_dir = old_value_query->column_bool(old_value_column + 3); | 838 bool old_is_dir = old_value_query->column_bool(old_value_column + 3); |
838 | 839 |
839 if (old_is_bookmark_object) { | 840 if (old_is_bookmark_object) { |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
879 "server_bookmark_url, " | 880 "server_bookmark_url, " |
880 "server_bookmark_favicon, " | 881 "server_bookmark_favicon, " |
881 "server_is_dir"), | 882 "server_is_dir"), |
882 "server_specifics", | 883 "server_specifics", |
883 &EncodeBookmarkURLAndFavicon)) { | 884 &EncodeBookmarkURLAndFavicon)) { |
884 return false; | 885 return false; |
885 } | 886 } |
886 | 887 |
887 // Lastly, fix up the "Google Chrome" folder, which is of the TOP_LEVEL_FOLDER | 888 // Lastly, fix up the "Google Chrome" folder, which is of the TOP_LEVEL_FOLDER |
888 // ModelType: it shouldn't have BookmarkSpecifics. | 889 // ModelType: it shouldn't have BookmarkSpecifics. |
889 SQLStatement clear_permanent_items; | 890 sqlite_utils::SQLStatement clear_permanent_items; |
890 clear_permanent_items.prepare(load_dbhandle_, | 891 clear_permanent_items.prepare(load_dbhandle_, |
891 "UPDATE metas SET specifics = NULL, server_specifics = NULL WHERE " | 892 "UPDATE metas SET specifics = NULL, server_specifics = NULL WHERE " |
892 "singleton_tag IN ('google_chrome')"); | 893 "singleton_tag IN ('google_chrome')"); |
893 if (clear_permanent_items.step() != SQLITE_DONE) | 894 if (clear_permanent_items.step() != SQLITE_DONE) |
894 return false; | 895 return false; |
895 | 896 |
896 SetVersion(69); | 897 SetVersion(69); |
897 needs_column_refresh_ = true; // Trigger deletion of old columns. | 898 needs_column_refresh_ = true; // Trigger deletion of old columns. |
898 return true; | 899 return true; |
899 } | 900 } |
900 | 901 |
901 // Version 71, the columns 'initial_sync_ended' and 'last_sync_timestamp' | 902 // Version 71, the columns 'initial_sync_ended' and 'last_sync_timestamp' |
902 // were removed from the share_info table. They were replaced by | 903 // were removed from the share_info table. They were replaced by |
903 // the 'models' table, which has these values on a per-datatype basis. | 904 // the 'models' table, which has these values on a per-datatype basis. |
904 bool DirectoryBackingStore::MigrateVersion70To71() { | 905 bool DirectoryBackingStore::MigrateVersion70To71() { |
905 if (SQLITE_DONE != CreateV71ModelsTable()) | 906 if (SQLITE_DONE != CreateV71ModelsTable()) |
906 return false; | 907 return false; |
907 | 908 |
908 // Move data from the old share_info columns to the new models table. | 909 // Move data from the old share_info columns to the new models table. |
909 { | 910 { |
910 SQLStatement fetch; | 911 sqlite_utils::SQLStatement fetch; |
911 fetch.prepare(load_dbhandle_, | 912 fetch.prepare(load_dbhandle_, |
912 "SELECT last_sync_timestamp, initial_sync_ended FROM share_info"); | 913 "SELECT last_sync_timestamp, initial_sync_ended FROM share_info"); |
913 | 914 |
914 if (SQLITE_ROW != fetch.step()) | 915 if (SQLITE_ROW != fetch.step()) |
915 return false; | 916 return false; |
916 int64 last_sync_timestamp = fetch.column_int64(0); | 917 int64 last_sync_timestamp = fetch.column_int64(0); |
917 bool initial_sync_ended = fetch.column_bool(1); | 918 bool initial_sync_ended = fetch.column_bool(1); |
918 if (SQLITE_DONE != fetch.step()) | 919 if (SQLITE_DONE != fetch.step()) |
919 return false; | 920 return false; |
920 SQLStatement update; | 921 sqlite_utils::SQLStatement update; |
921 update.prepare(load_dbhandle_, "INSERT INTO models (model_id, " | 922 update.prepare(load_dbhandle_, "INSERT INTO models (model_id, " |
922 "last_download_timestamp, initial_sync_ended) VALUES (?, ?, ?)"); | 923 "last_download_timestamp, initial_sync_ended) VALUES (?, ?, ?)"); |
923 string bookmark_model_id = ModelTypeEnumToModelId(BOOKMARKS); | 924 string bookmark_model_id = ModelTypeEnumToModelId(BOOKMARKS); |
924 update.bind_blob(0, bookmark_model_id.data(), bookmark_model_id.size()); | 925 update.bind_blob(0, bookmark_model_id.data(), bookmark_model_id.size()); |
925 update.bind_int64(1, last_sync_timestamp); | 926 update.bind_int64(1, last_sync_timestamp); |
926 update.bind_bool(2, initial_sync_ended); | 927 update.bind_bool(2, initial_sync_ended); |
927 if (SQLITE_DONE != update.step()) | 928 if (SQLITE_DONE != update.step()) |
928 return false; | 929 return false; |
929 } | 930 } |
930 | 931 |
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1032 // last_download_timestamp, thereby preserving the download state. | 1033 // last_download_timestamp, thereby preserving the download state. |
1033 | 1034 |
1034 // Move aside the old table and create a new empty one at the current schema. | 1035 // Move aside the old table and create a new empty one at the current schema. |
1035 if (SQLITE_DONE != ExecQuery(load_dbhandle_, | 1036 if (SQLITE_DONE != ExecQuery(load_dbhandle_, |
1036 "ALTER TABLE models RENAME TO temp_models")) { | 1037 "ALTER TABLE models RENAME TO temp_models")) { |
1037 return false; | 1038 return false; |
1038 } | 1039 } |
1039 if (!CreateModelsTable()) | 1040 if (!CreateModelsTable()) |
1040 return false; | 1041 return false; |
1041 | 1042 |
1042 SQLStatement query; | 1043 sqlite_utils::SQLStatement query; |
1043 query.prepare(load_dbhandle_, | 1044 query.prepare(load_dbhandle_, |
1044 "SELECT model_id, last_download_timestamp, initial_sync_ended " | 1045 "SELECT model_id, last_download_timestamp, initial_sync_ended " |
1045 "FROM temp_models"); | 1046 "FROM temp_models"); |
1046 while (SQLITE_ROW == query.step()) { | 1047 while (SQLITE_ROW == query.step()) { |
1047 ModelType type = ModelIdToModelTypeEnum(query.column_blob(0), | 1048 ModelType type = ModelIdToModelTypeEnum(query.column_blob(0), |
1048 query.column_bytes(0)); | 1049 query.column_bytes(0)); |
1049 if (type != UNSPECIFIED) { | 1050 if (type != UNSPECIFIED) { |
1050 // Set the |timestamp_token_for_migration| on a new | 1051 // Set the |timestamp_token_for_migration| on a new |
1051 // DataTypeProgressMarker, using the old value of last_download_timestamp. | 1052 // DataTypeProgressMarker, using the old value of last_download_timestamp. |
1052 // The server will turn this into a real token on our behalf the next | 1053 // The server will turn this into a real token on our behalf the next |
1053 // time we check for updates. | 1054 // time we check for updates. |
1054 sync_pb::DataTypeProgressMarker progress_marker; | 1055 sync_pb::DataTypeProgressMarker progress_marker; |
1055 progress_marker.set_data_type_id( | 1056 progress_marker.set_data_type_id( |
1056 GetExtensionFieldNumberFromModelType(type)); | 1057 GetExtensionFieldNumberFromModelType(type)); |
1057 progress_marker.set_timestamp_token_for_migration(query.column_int64(1)); | 1058 progress_marker.set_timestamp_token_for_migration(query.column_int64(1)); |
1058 std::string progress_blob; | 1059 std::string progress_blob; |
1059 progress_marker.SerializeToString(&progress_blob); | 1060 progress_marker.SerializeToString(&progress_blob); |
1060 | 1061 |
1061 SQLStatement update; | 1062 sqlite_utils::SQLStatement update; |
1062 update.prepare(load_dbhandle_, "INSERT INTO models (model_id, " | 1063 update.prepare(load_dbhandle_, "INSERT INTO models (model_id, " |
1063 "progress_marker, initial_sync_ended) VALUES (?, ?, ?)"); | 1064 "progress_marker, initial_sync_ended) VALUES (?, ?, ?)"); |
1064 update.bind_blob(0, query.column_blob(0), query.column_bytes(0)); | 1065 update.bind_blob(0, query.column_blob(0), query.column_bytes(0)); |
1065 update.bind_blob(1, progress_blob.data(), progress_blob.length()); | 1066 update.bind_blob(1, progress_blob.data(), progress_blob.length()); |
1066 update.bind_bool(2, query.column_bool(2)); | 1067 update.bind_bool(2, query.column_bool(2)); |
1067 if (SQLITE_DONE != update.step()) | 1068 if (SQLITE_DONE != update.step()) |
1068 return false; | 1069 return false; |
1069 } | 1070 } |
1070 } | 1071 } |
1071 // Drop the old table. | 1072 // Drop the old table. |
(...skipping 18 matching lines...) Expand all Loading... |
1090 | 1091 |
1091 int DirectoryBackingStore::CreateTables() { | 1092 int DirectoryBackingStore::CreateTables() { |
1092 VLOG(1) << "First run, creating tables"; | 1093 VLOG(1) << "First run, creating tables"; |
1093 // Create two little tables share_version and share_info | 1094 // Create two little tables share_version and share_info |
1094 int result = ExecQuery(load_dbhandle_, | 1095 int result = ExecQuery(load_dbhandle_, |
1095 "CREATE TABLE share_version (" | 1096 "CREATE TABLE share_version (" |
1096 "id VARCHAR(128) primary key, data INT)"); | 1097 "id VARCHAR(128) primary key, data INT)"); |
1097 if (result != SQLITE_DONE) | 1098 if (result != SQLITE_DONE) |
1098 return result; | 1099 return result; |
1099 { | 1100 { |
1100 SQLStatement statement; | 1101 sqlite_utils::SQLStatement statement; |
1101 statement.prepare(load_dbhandle_, "INSERT INTO share_version VALUES(?, ?)"); | 1102 statement.prepare(load_dbhandle_, "INSERT INTO share_version VALUES(?, ?)"); |
1102 statement.bind_string(0, dir_name_); | 1103 statement.bind_string(0, dir_name_); |
1103 statement.bind_int(1, kCurrentDBVersion); | 1104 statement.bind_int(1, kCurrentDBVersion); |
1104 result = statement.step(); | 1105 result = statement.step(); |
1105 } | 1106 } |
1106 if (result != SQLITE_DONE) | 1107 if (result != SQLITE_DONE) |
1107 return result; | 1108 return result; |
1108 | 1109 |
1109 const bool kCreateAsTempShareInfo = false; | 1110 const bool kCreateAsTempShareInfo = false; |
1110 result = CreateShareInfoTable(kCreateAsTempShareInfo); | 1111 result = CreateShareInfoTable(kCreateAsTempShareInfo); |
1111 if (result != SQLITE_DONE) | 1112 if (result != SQLITE_DONE) |
1112 return result; | 1113 return result; |
1113 { | 1114 { |
1114 SQLStatement statement; | 1115 sqlite_utils::SQLStatement statement; |
1115 statement.prepare(load_dbhandle_, "INSERT INTO share_info VALUES" | 1116 statement.prepare(load_dbhandle_, "INSERT INTO share_info VALUES" |
1116 "(?, " // id | 1117 "(?, " // id |
1117 "?, " // name | 1118 "?, " // name |
1118 "?, " // store_birthday | 1119 "?, " // store_birthday |
1119 "?, " // db_create_version | 1120 "?, " // db_create_version |
1120 "?, " // db_create_time | 1121 "?, " // db_create_time |
1121 "-2, " // next_id | 1122 "-2, " // next_id |
1122 "?, " // cache_guid | 1123 "?, " // cache_guid |
1123 "?);"); // notification_state | 1124 "?);"); // notification_state |
1124 statement.bind_string(0, dir_name_); // id | 1125 statement.bind_string(0, dir_name_); // id |
(...skipping 11 matching lines...) Expand all Loading... |
1136 result = CreateModelsTable(); | 1137 result = CreateModelsTable(); |
1137 if (result != SQLITE_DONE) | 1138 if (result != SQLITE_DONE) |
1138 return result; | 1139 return result; |
1139 // Create the big metas table. | 1140 // Create the big metas table. |
1140 result = CreateMetasTable(false); | 1141 result = CreateMetasTable(false); |
1141 if (result != SQLITE_DONE) | 1142 if (result != SQLITE_DONE) |
1142 return result; | 1143 return result; |
1143 { | 1144 { |
1144 // Insert the entry for the root into the metas table. | 1145 // Insert the entry for the root into the metas table. |
1145 const int64 now = Now(); | 1146 const int64 now = Now(); |
1146 SQLStatement statement; | 1147 sqlite_utils::SQLStatement statement; |
1147 statement.prepare(load_dbhandle_, | 1148 statement.prepare(load_dbhandle_, |
1148 "INSERT INTO metas " | 1149 "INSERT INTO metas " |
1149 "( id, metahandle, is_dir, ctime, mtime) " | 1150 "( id, metahandle, is_dir, ctime, mtime) " |
1150 "VALUES ( \"r\", 1, 1, ?, ?)"); | 1151 "VALUES ( \"r\", 1, 1, ?, ?)"); |
1151 statement.bind_int64(0, now); | 1152 statement.bind_int64(0, now); |
1152 statement.bind_int64(1, now); | 1153 statement.bind_int64(1, now); |
1153 result = statement.step(); | 1154 result = statement.step(); |
1154 } | 1155 } |
1155 return result; | 1156 return result; |
1156 } | 1157 } |
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1227 "id TEXT primary key, " | 1228 "id TEXT primary key, " |
1228 "name TEXT, " | 1229 "name TEXT, " |
1229 "store_birthday TEXT, " | 1230 "store_birthday TEXT, " |
1230 "db_create_version TEXT, " | 1231 "db_create_version TEXT, " |
1231 "db_create_time INT, " | 1232 "db_create_time INT, " |
1232 "next_id INT default -2, " | 1233 "next_id INT default -2, " |
1233 "cache_guid TEXT )"); | 1234 "cache_guid TEXT )"); |
1234 return ExecQuery(load_dbhandle_, query.c_str()); | 1235 return ExecQuery(load_dbhandle_, query.c_str()); |
1235 } | 1236 } |
1236 } // namespace syncable | 1237 } // namespace syncable |
OLD | NEW |