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 "webkit/appcache/appcache_database.h" | 5 #include "webkit/appcache/appcache_database.h" |
6 | 6 |
7 #include "base/auto_reset.h" | 7 #include "base/auto_reset.h" |
8 #include "base/file_util.h" | 8 #include "base/file_util.h" |
9 #include "base/logging.h" | 9 #include "base/logging.h" |
10 #include "base/utf_string_conversions.h" | 10 #include "base/utf_string_conversions.h" |
11 #include "sql/connection.h" | 11 #include "sql/connection.h" |
12 #include "sql/diagnostic_error_delegate.h" | 12 #include "sql/diagnostic_error_delegate.h" |
13 #include "sql/meta_table.h" | 13 #include "sql/meta_table.h" |
14 #include "sql/statement.h" | 14 #include "sql/statement.h" |
15 #include "sql/transaction.h" | 15 #include "sql/transaction.h" |
16 #include "webkit/appcache/appcache_entry.h" | 16 #include "webkit/appcache/appcache_entry.h" |
17 #include "webkit/appcache/appcache_histograms.h" | 17 #include "webkit/appcache/appcache_histograms.h" |
18 | 18 |
19 // Schema ------------------------------------------------------------------- | 19 // Schema ------------------------------------------------------------------- |
20 namespace { | 20 namespace { |
21 | 21 |
22 const int kCurrentVersion = 3; | 22 const int kCurrentVersion = 4; |
23 const int kCompatibleVersion = 3; | 23 const int kCompatibleVersion = 4; |
24 | 24 |
25 const char kGroupsTable[] = "Groups"; | 25 const char kGroupsTable[] = "Groups"; |
26 const char kCachesTable[] = "Caches"; | 26 const char kCachesTable[] = "Caches"; |
27 const char kEntriesTable[] = "Entries"; | 27 const char kEntriesTable[] = "Entries"; |
28 const char kFallbackNameSpacesTable[] = "FallbackNameSpaces"; | 28 const char kNamespacesTable[] = "Namespaces"; |
29 const char kOnlineWhiteListsTable[] = "OnlineWhiteLists"; | 29 const char kOnlineWhiteListsTable[] = "OnlineWhiteLists"; |
30 const char kDeletableResponseIdsTable[] = "DeletableResponseIds"; | 30 const char kDeletableResponseIdsTable[] = "DeletableResponseIds"; |
31 | 31 |
32 const struct { | 32 struct TableInfo { |
33 const char* table_name; | 33 const char* table_name; |
34 const char* columns; | 34 const char* columns; |
35 } kTables[] = { | 35 }; |
| 36 |
| 37 struct IndexInfo { |
| 38 const char* index_name; |
| 39 const char* table_name; |
| 40 const char* columns; |
| 41 bool unique; |
| 42 }; |
| 43 |
| 44 const TableInfo kTables[] = { |
36 { kGroupsTable, | 45 { kGroupsTable, |
37 "(group_id INTEGER PRIMARY KEY," | 46 "(group_id INTEGER PRIMARY KEY," |
38 " origin TEXT," | 47 " origin TEXT," |
39 " manifest_url TEXT," | 48 " manifest_url TEXT," |
40 " creation_time INTEGER," | 49 " creation_time INTEGER," |
41 " last_access_time INTEGER)" }, | 50 " last_access_time INTEGER)" }, |
42 | 51 |
43 { kCachesTable, | 52 { kCachesTable, |
44 "(cache_id INTEGER PRIMARY KEY," | 53 "(cache_id INTEGER PRIMARY KEY," |
45 " group_id INTEGER," | 54 " group_id INTEGER," |
46 " online_wildcard INTEGER CHECK(online_wildcard IN (0, 1))," | 55 " online_wildcard INTEGER CHECK(online_wildcard IN (0, 1))," |
47 " update_time INTEGER," | 56 " update_time INTEGER," |
48 " cache_size INTEGER)" }, // intentionally not normalized | 57 " cache_size INTEGER)" }, // intentionally not normalized |
49 | 58 |
50 { kEntriesTable, | 59 { kEntriesTable, |
51 "(cache_id INTEGER," | 60 "(cache_id INTEGER," |
52 " url TEXT," | 61 " url TEXT," |
53 " flags INTEGER," | 62 " flags INTEGER," |
54 " response_id INTEGER," | 63 " response_id INTEGER," |
55 " response_size INTEGER)" }, | 64 " response_size INTEGER)" }, |
56 | 65 |
57 { kFallbackNameSpacesTable, | 66 { kNamespacesTable, |
58 "(cache_id INTEGER," | 67 "(cache_id INTEGER," |
59 " origin TEXT," // intentionally not normalized | 68 " origin TEXT," // intentionally not normalized |
| 69 " type INTEGER," |
60 " namespace_url TEXT," | 70 " namespace_url TEXT," |
61 " fallback_entry_url TEXT)" }, | 71 " target_url TEXT)" }, |
62 | 72 |
63 { kOnlineWhiteListsTable, | 73 { kOnlineWhiteListsTable, |
64 "(cache_id INTEGER," | 74 "(cache_id INTEGER," |
65 " namespace_url TEXT)" }, | 75 " namespace_url TEXT)" }, |
66 | 76 |
67 { kDeletableResponseIdsTable, | 77 { kDeletableResponseIdsTable, |
68 "(response_id INTEGER NOT NULL)" }, | 78 "(response_id INTEGER NOT NULL)" }, |
69 }; | 79 }; |
70 | 80 |
71 const struct { | 81 const IndexInfo kIndexes[] = { |
72 const char* index_name; | |
73 const char* table_name; | |
74 const char* columns; | |
75 bool unique; | |
76 } kIndexes[] = { | |
77 { "GroupsOriginIndex", | 82 { "GroupsOriginIndex", |
78 kGroupsTable, | 83 kGroupsTable, |
79 "(origin)", | 84 "(origin)", |
80 false }, | 85 false }, |
81 | 86 |
82 { "GroupsManifestIndex", | 87 { "GroupsManifestIndex", |
83 kGroupsTable, | 88 kGroupsTable, |
84 "(manifest_url)", | 89 "(manifest_url)", |
85 true }, | 90 true }, |
86 | 91 |
(...skipping 10 matching lines...) Expand all Loading... |
97 { "EntriesCacheAndUrlIndex", | 102 { "EntriesCacheAndUrlIndex", |
98 kEntriesTable, | 103 kEntriesTable, |
99 "(cache_id, url)", | 104 "(cache_id, url)", |
100 true }, | 105 true }, |
101 | 106 |
102 { "EntriesResponseIdIndex", | 107 { "EntriesResponseIdIndex", |
103 kEntriesTable, | 108 kEntriesTable, |
104 "(response_id)", | 109 "(response_id)", |
105 true }, | 110 true }, |
106 | 111 |
107 { "FallbackNameSpacesCacheIndex", | 112 { "NamespacesCacheIndex", |
108 kFallbackNameSpacesTable, | 113 kNamespacesTable, |
109 "(cache_id)", | 114 "(cache_id)", |
110 false }, | 115 false }, |
111 | 116 |
112 { "FallbackNameSpacesOriginIndex", | 117 { "NamespacesOriginIndex", |
113 kFallbackNameSpacesTable, | 118 kNamespacesTable, |
114 "(origin)", | 119 "(origin)", |
115 false }, | 120 false }, |
116 | 121 |
117 { "FallbackNameSpacesCacheAndUrlIndex", | 122 { "NamespacesCacheAndUrlIndex", |
118 kFallbackNameSpacesTable, | 123 kNamespacesTable, |
119 "(cache_id, namespace_url)", | 124 "(cache_id, namespace_url)", |
120 true }, | 125 true }, |
121 | 126 |
122 { "OnlineWhiteListCacheIndex", | 127 { "OnlineWhiteListCacheIndex", |
123 kOnlineWhiteListsTable, | 128 kOnlineWhiteListsTable, |
124 "(cache_id)", | 129 "(cache_id)", |
125 false }, | 130 false }, |
126 | 131 |
127 { "DeletableResponsesIdIndex", | 132 { "DeletableResponsesIdIndex", |
128 kDeletableResponseIdsTable, | 133 kDeletableResponseIdsTable, |
129 "(response_id)", | 134 "(response_id)", |
130 true }, | 135 true }, |
131 }; | 136 }; |
132 | 137 |
133 const int kTableCount = ARRAYSIZE_UNSAFE(kTables); | 138 const int kTableCount = ARRAYSIZE_UNSAFE(kTables); |
134 const int kIndexCount = ARRAYSIZE_UNSAFE(kIndexes); | 139 const int kIndexCount = ARRAYSIZE_UNSAFE(kIndexes); |
135 | 140 |
136 class HistogramUniquifier { | 141 class HistogramUniquifier { |
137 public: | 142 public: |
138 static const char* name() { return "Sqlite.AppCache.Error"; } | 143 static const char* name() { return "Sqlite.AppCache.Error"; } |
139 }; | 144 }; |
140 | 145 |
141 sql::ErrorDelegate* GetErrorHandlerForAppCacheDb() { | 146 sql::ErrorDelegate* GetErrorHandlerForAppCacheDb() { |
142 return new sql::DiagnosticErrorDelegate<HistogramUniquifier>(); | 147 return new sql::DiagnosticErrorDelegate<HistogramUniquifier>(); |
143 } | 148 } |
144 | 149 |
| 150 bool CreateTable(sql::Connection* db, const TableInfo& info) { |
| 151 std::string sql("CREATE TABLE "); |
| 152 sql += info.table_name; |
| 153 sql += info.columns; |
| 154 return db->Execute(sql.c_str()); |
| 155 } |
| 156 |
| 157 bool CreateIndex(sql::Connection* db, const IndexInfo& info) { |
| 158 std::string sql; |
| 159 if (info.unique) |
| 160 sql += "CREATE UNIQUE INDEX "; |
| 161 else |
| 162 sql += "CREATE INDEX "; |
| 163 sql += info.index_name; |
| 164 sql += " ON "; |
| 165 sql += info.table_name; |
| 166 sql += info.columns; |
| 167 return db->Execute(sql.c_str()); |
| 168 } |
| 169 |
145 } // anon namespace | 170 } // anon namespace |
146 | 171 |
147 // AppCacheDatabase ---------------------------------------------------------- | 172 // AppCacheDatabase ---------------------------------------------------------- |
148 namespace appcache { | 173 namespace appcache { |
149 | 174 |
150 AppCacheDatabase::GroupRecord::GroupRecord() | 175 AppCacheDatabase::GroupRecord::GroupRecord() |
151 : group_id(0) { | 176 : group_id(0) { |
152 } | 177 } |
153 | 178 |
154 AppCacheDatabase::GroupRecord::~GroupRecord() { | 179 AppCacheDatabase::GroupRecord::~GroupRecord() { |
155 } | 180 } |
156 | 181 |
157 AppCacheDatabase::FallbackNameSpaceRecord::FallbackNameSpaceRecord() | 182 AppCacheDatabase::NamespaceRecord::NamespaceRecord() |
158 : cache_id(0) { | 183 : cache_id(0), type(FALLBACK_NAMESPACE) { |
159 } | 184 } |
160 | 185 |
161 AppCacheDatabase::FallbackNameSpaceRecord::~FallbackNameSpaceRecord() { | 186 AppCacheDatabase::NamespaceRecord::~NamespaceRecord() { |
162 } | 187 } |
163 | 188 |
| 189 |
164 AppCacheDatabase::AppCacheDatabase(const FilePath& path) | 190 AppCacheDatabase::AppCacheDatabase(const FilePath& path) |
165 : db_file_path_(path), is_disabled_(false), is_recreating_(false) { | 191 : db_file_path_(path), is_disabled_(false), is_recreating_(false) { |
166 } | 192 } |
167 | 193 |
168 AppCacheDatabase::~AppCacheDatabase() { | 194 AppCacheDatabase::~AppCacheDatabase() { |
169 } | 195 } |
170 | 196 |
171 void AppCacheDatabase::CloseConnection() { | 197 void AppCacheDatabase::CloseConnection() { |
172 // We can't close the connection for an in-memory database w/o | 198 // We can't close the connection for an in-memory database w/o |
173 // losing all of the data, so we don't do that. | 199 // losing all of the data, so we don't do that. |
(...skipping 474 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
648 sql::Statement statement; | 674 sql::Statement statement; |
649 if (!PrepareCachedStatement(SQL_FROM_HERE, kSql, &statement)) | 675 if (!PrepareCachedStatement(SQL_FROM_HERE, kSql, &statement)) |
650 return false; | 676 return false; |
651 | 677 |
652 statement.BindInt(0, additional_flags); | 678 statement.BindInt(0, additional_flags); |
653 statement.BindInt64(1, cache_id); | 679 statement.BindInt64(1, cache_id); |
654 statement.BindString(2, entry_url.spec()); | 680 statement.BindString(2, entry_url.spec()); |
655 return statement.Run() && db_->GetLastChangeCount(); | 681 return statement.Run() && db_->GetLastChangeCount(); |
656 } | 682 } |
657 | 683 |
658 bool AppCacheDatabase::FindFallbackNameSpacesForOrigin( | 684 bool AppCacheDatabase::FindNamespacesForOrigin( |
659 const GURL& origin, std::vector<FallbackNameSpaceRecord>* records) { | 685 const GURL& origin, |
660 DCHECK(records && records->empty()); | 686 std::vector<NamespaceRecord>* intercepts, |
| 687 std::vector<NamespaceRecord>* fallbacks) { |
| 688 DCHECK(intercepts && intercepts->empty()); |
| 689 DCHECK(fallbacks && fallbacks->empty()); |
661 if (!LazyOpen(false)) | 690 if (!LazyOpen(false)) |
662 return false; | 691 return false; |
663 | 692 |
664 const char* kSql = | 693 const char* kSql = |
665 "SELECT cache_id, origin, namespace_url, fallback_entry_url" | 694 "SELECT cache_id, origin, type, namespace_url, target_url" |
666 " FROM FallbackNameSpaces WHERE origin = ?"; | 695 " FROM Namespaces WHERE origin = ?"; |
667 | 696 |
668 sql::Statement statement; | 697 sql::Statement statement; |
669 if (!PrepareCachedStatement(SQL_FROM_HERE, kSql, &statement)) | 698 if (!PrepareCachedStatement(SQL_FROM_HERE, kSql, &statement)) |
670 return false; | 699 return false; |
671 | 700 |
672 statement.BindString(0, origin.spec()); | 701 statement.BindString(0, origin.spec()); |
673 while (statement.Step()) { | 702 ReadNamespaceRecords(&statement, intercepts, fallbacks); |
674 records->push_back(FallbackNameSpaceRecord()); | |
675 ReadFallbackNameSpaceRecord(statement, &records->back()); | |
676 DCHECK(records->back().origin == origin); | |
677 } | |
678 return statement.Succeeded(); | 703 return statement.Succeeded(); |
679 } | 704 } |
680 | 705 |
681 bool AppCacheDatabase::FindFallbackNameSpacesForCache( | 706 bool AppCacheDatabase::FindNamespacesForCache( |
682 int64 cache_id, std::vector<FallbackNameSpaceRecord>* records) { | 707 int64 cache_id, |
683 DCHECK(records && records->empty()); | 708 std::vector<NamespaceRecord>* intercepts, |
| 709 std::vector<NamespaceRecord>* fallbacks) { |
| 710 DCHECK(intercepts && intercepts->empty()); |
| 711 DCHECK(fallbacks && fallbacks->empty()); |
684 if (!LazyOpen(false)) | 712 if (!LazyOpen(false)) |
685 return false; | 713 return false; |
686 | 714 |
687 const char* kSql = | 715 const char* kSql = |
688 "SELECT cache_id, origin, namespace_url, fallback_entry_url" | 716 "SELECT cache_id, origin, type, namespace_url, target_url" |
689 " FROM FallbackNameSpaces WHERE cache_id = ?"; | 717 " FROM Namespaces WHERE cache_id = ?"; |
690 | 718 |
691 sql::Statement statement; | 719 sql::Statement statement; |
692 if (!PrepareCachedStatement(SQL_FROM_HERE, kSql, &statement)) | 720 if (!PrepareCachedStatement(SQL_FROM_HERE, kSql, &statement)) |
693 return false; | 721 return false; |
694 | 722 |
695 statement.BindInt64(0, cache_id); | 723 statement.BindInt64(0, cache_id); |
696 while (statement.Step()) { | 724 ReadNamespaceRecords(&statement, intercepts, fallbacks); |
697 records->push_back(FallbackNameSpaceRecord()); | |
698 ReadFallbackNameSpaceRecord(statement, &records->back()); | |
699 DCHECK(records->back().cache_id == cache_id); | |
700 } | |
701 return statement.Succeeded(); | 725 return statement.Succeeded(); |
702 } | 726 } |
703 | 727 |
704 bool AppCacheDatabase::InsertFallbackNameSpace( | 728 bool AppCacheDatabase::InsertNamespace( |
705 const FallbackNameSpaceRecord* record) { | 729 const NamespaceRecord* record) { |
706 if (!LazyOpen(true)) | 730 if (!LazyOpen(true)) |
707 return false; | 731 return false; |
708 | 732 |
709 const char* kSql = | 733 const char* kSql = |
710 "INSERT INTO FallbackNameSpaces" | 734 "INSERT INTO Namespaces" |
711 " (cache_id, origin, namespace_url, fallback_entry_url)" | 735 " (cache_id, origin, type, namespace_url, target_url)" |
712 " VALUES (?, ?, ?, ?)"; | 736 " VALUES (?, ?, ?, ?, ?)"; |
713 | 737 |
714 sql::Statement statement; | 738 sql::Statement statement; |
715 if (!PrepareCachedStatement(SQL_FROM_HERE, kSql, &statement)) | 739 if (!PrepareCachedStatement(SQL_FROM_HERE, kSql, &statement)) |
716 return false; | 740 return false; |
717 | 741 |
718 statement.BindInt64(0, record->cache_id); | 742 statement.BindInt64(0, record->cache_id); |
719 statement.BindString(1, record->origin.spec()); | 743 statement.BindString(1, record->origin.spec()); |
720 statement.BindString(2, record->namespace_url.spec()); | 744 statement.BindInt(2, record->type); |
721 statement.BindString(3, record->fallback_entry_url.spec()); | 745 statement.BindString(3, record->namespace_url.spec()); |
| 746 statement.BindString(4, record->target_url.spec()); |
722 return statement.Run(); | 747 return statement.Run(); |
723 } | 748 } |
724 | 749 |
725 bool AppCacheDatabase::InsertFallbackNameSpaceRecords( | 750 bool AppCacheDatabase::InsertNamespaceRecords( |
726 const std::vector<FallbackNameSpaceRecord>& records) { | 751 const std::vector<NamespaceRecord>& records) { |
727 if (records.empty()) | 752 if (records.empty()) |
728 return true; | 753 return true; |
729 sql::Transaction transaction(db_.get()); | 754 sql::Transaction transaction(db_.get()); |
730 if (!transaction.Begin()) | 755 if (!transaction.Begin()) |
731 return false; | 756 return false; |
732 std::vector<FallbackNameSpaceRecord>::const_iterator iter = records.begin(); | 757 std::vector<NamespaceRecord>::const_iterator iter = records.begin(); |
733 while (iter != records.end()) { | 758 while (iter != records.end()) { |
734 if (!InsertFallbackNameSpace(&(*iter))) | 759 if (!InsertNamespace(&(*iter))) |
735 return false; | 760 return false; |
736 ++iter; | 761 ++iter; |
737 } | 762 } |
738 return transaction.Commit(); | 763 return transaction.Commit(); |
739 } | 764 } |
740 | 765 |
741 bool AppCacheDatabase::DeleteFallbackNameSpacesForCache(int64 cache_id) { | 766 bool AppCacheDatabase::DeleteNamespacesForCache(int64 cache_id) { |
742 if (!LazyOpen(false)) | 767 if (!LazyOpen(false)) |
743 return false; | 768 return false; |
744 | 769 |
745 const char* kSql = | 770 const char* kSql = |
746 "DELETE FROM FallbackNameSpaces WHERE cache_id = ?"; | 771 "DELETE FROM Namespaces WHERE cache_id = ?"; |
747 | 772 |
748 sql::Statement statement; | 773 sql::Statement statement; |
749 if (!PrepareCachedStatement(SQL_FROM_HERE, kSql, &statement)) | 774 if (!PrepareCachedStatement(SQL_FROM_HERE, kSql, &statement)) |
750 return false; | 775 return false; |
751 | 776 |
752 statement.BindInt64(0, cache_id); | 777 statement.BindInt64(0, cache_id); |
753 return statement.Run(); | 778 return statement.Run(); |
754 } | 779 } |
755 | 780 |
756 bool AppCacheDatabase::FindOnlineWhiteListForCache( | 781 bool AppCacheDatabase::FindOnlineWhiteListForCache( |
(...skipping 210 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
967 | 992 |
968 void AppCacheDatabase::ReadEntryRecord( | 993 void AppCacheDatabase::ReadEntryRecord( |
969 const sql::Statement& statement, EntryRecord* record) { | 994 const sql::Statement& statement, EntryRecord* record) { |
970 record->cache_id = statement.ColumnInt64(0); | 995 record->cache_id = statement.ColumnInt64(0); |
971 record->url = GURL(statement.ColumnString(1)); | 996 record->url = GURL(statement.ColumnString(1)); |
972 record->flags = statement.ColumnInt(2); | 997 record->flags = statement.ColumnInt(2); |
973 record->response_id = statement.ColumnInt64(3); | 998 record->response_id = statement.ColumnInt64(3); |
974 record->response_size = statement.ColumnInt64(4); | 999 record->response_size = statement.ColumnInt64(4); |
975 } | 1000 } |
976 | 1001 |
977 void AppCacheDatabase::ReadFallbackNameSpaceRecord( | 1002 void AppCacheDatabase::ReadNamespaceRecords( |
978 const sql::Statement& statement, FallbackNameSpaceRecord* record) { | 1003 sql::Statement* statement, |
979 record->cache_id = statement.ColumnInt64(0); | 1004 NamespaceRecordVector* intercepts, |
980 record->origin = GURL(statement.ColumnString(1)); | 1005 NamespaceRecordVector* fallbacks) { |
981 record->namespace_url = GURL(statement.ColumnString(2)); | 1006 while (statement->Step()) { |
982 record->fallback_entry_url = GURL(statement.ColumnString(3)); | 1007 NamespaceType type = static_cast<NamespaceType>(statement->ColumnInt(2)); |
| 1008 NamespaceRecordVector* records = |
| 1009 (type == FALLBACK_NAMESPACE) ? fallbacks : intercepts; |
| 1010 records->push_back(NamespaceRecord()); |
| 1011 ReadNamespaceRecord(statement, &records->back()); |
| 1012 } |
| 1013 } |
| 1014 |
| 1015 void AppCacheDatabase::ReadNamespaceRecord( |
| 1016 const sql::Statement* statement, NamespaceRecord* record) { |
| 1017 record->cache_id = statement->ColumnInt64(0); |
| 1018 record->origin = GURL(statement->ColumnString(1)); |
| 1019 record->type = static_cast<NamespaceType>(statement->ColumnInt(2)); |
| 1020 record->namespace_url = GURL(statement->ColumnString(3)); |
| 1021 record->target_url = GURL(statement->ColumnString(4)); |
983 } | 1022 } |
984 | 1023 |
985 void AppCacheDatabase::ReadOnlineWhiteListRecord( | 1024 void AppCacheDatabase::ReadOnlineWhiteListRecord( |
986 const sql::Statement& statement, OnlineWhiteListRecord* record) { | 1025 const sql::Statement& statement, OnlineWhiteListRecord* record) { |
987 record->cache_id = statement.ColumnInt64(0); | 1026 record->cache_id = statement.ColumnInt64(0); |
988 record->namespace_url = GURL(statement.ColumnString(1)); | 1027 record->namespace_url = GURL(statement.ColumnString(1)); |
989 } | 1028 } |
990 | 1029 |
991 bool AppCacheDatabase::LazyOpen(bool create_if_needed) { | 1030 bool AppCacheDatabase::LazyOpen(bool create_if_needed) { |
992 if (db_.get()) | 1031 if (db_.get()) |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1053 } | 1092 } |
1054 | 1093 |
1055 if (meta_table_->GetVersionNumber() < kCurrentVersion) | 1094 if (meta_table_->GetVersionNumber() < kCurrentVersion) |
1056 return UpgradeSchema(); | 1095 return UpgradeSchema(); |
1057 | 1096 |
1058 #ifndef NDEBUG | 1097 #ifndef NDEBUG |
1059 DCHECK(sql::MetaTable::DoesTableExist(db_.get())); | 1098 DCHECK(sql::MetaTable::DoesTableExist(db_.get())); |
1060 for (int i = 0; i < kTableCount; ++i) { | 1099 for (int i = 0; i < kTableCount; ++i) { |
1061 DCHECK(db_->DoesTableExist(kTables[i].table_name)); | 1100 DCHECK(db_->DoesTableExist(kTables[i].table_name)); |
1062 } | 1101 } |
| 1102 for (int i = 0; i < kIndexCount; ++i) { |
| 1103 DCHECK(db_->DoesIndexExist(kIndexes[i].index_name)); |
| 1104 } |
1063 #endif | 1105 #endif |
1064 | 1106 |
1065 return true; | 1107 return true; |
1066 } | 1108 } |
1067 | 1109 |
1068 bool AppCacheDatabase::CreateSchema() { | 1110 bool AppCacheDatabase::CreateSchema() { |
1069 sql::Transaction transaction(db_.get()); | 1111 sql::Transaction transaction(db_.get()); |
1070 if (!transaction.Begin()) | 1112 if (!transaction.Begin()) |
1071 return false; | 1113 return false; |
1072 | 1114 |
1073 if (!meta_table_->Init(db_.get(), kCurrentVersion, kCompatibleVersion)) | 1115 if (!meta_table_->Init(db_.get(), kCurrentVersion, kCompatibleVersion)) |
1074 return false; | 1116 return false; |
1075 | 1117 |
1076 for (int i = 0; i < kTableCount; ++i) { | 1118 for (int i = 0; i < kTableCount; ++i) { |
1077 std::string sql("CREATE TABLE "); | 1119 if (!CreateTable(db_.get(), kTables[i])) |
1078 sql += kTables[i].table_name; | |
1079 sql += kTables[i].columns; | |
1080 if (!db_->Execute(sql.c_str())) | |
1081 return false; | 1120 return false; |
1082 } | 1121 } |
1083 | 1122 |
1084 for (int i = 0; i < kIndexCount; ++i) { | 1123 for (int i = 0; i < kIndexCount; ++i) { |
1085 std::string sql; | 1124 if (!CreateIndex(db_.get(), kIndexes[i])) |
1086 if (kIndexes[i].unique) | |
1087 sql += "CREATE UNIQUE INDEX "; | |
1088 else | |
1089 sql += "CREATE INDEX "; | |
1090 sql += kIndexes[i].index_name; | |
1091 sql += " ON "; | |
1092 sql += kIndexes[i].table_name; | |
1093 sql += kIndexes[i].columns; | |
1094 if (!db_->Execute(sql.c_str())) | |
1095 return false; | 1125 return false; |
1096 } | 1126 } |
1097 | 1127 |
1098 return transaction.Commit(); | 1128 return transaction.Commit(); |
1099 } | 1129 } |
1100 | 1130 |
1101 bool AppCacheDatabase::UpgradeSchema() { | 1131 bool AppCacheDatabase::UpgradeSchema() { |
1102 // Upgrade logic goes here | 1132 if (meta_table_->GetVersionNumber() == 3) { |
| 1133 DCHECK_EQ(strcmp(kNamespacesTable, kTables[3].table_name), 0); |
| 1134 DCHECK_EQ(strcmp(kNamespacesTable, kIndexes[6].table_name), 0); |
| 1135 DCHECK_EQ(strcmp(kNamespacesTable, kIndexes[7].table_name), 0); |
| 1136 DCHECK_EQ(strcmp(kNamespacesTable, kIndexes[8].table_name), 0); |
| 1137 |
| 1138 // Migrate from the old "FallbackNameSpaces" to the new "Namespaces" table. |
| 1139 sql::Transaction transaction(db_.get()); |
| 1140 if (!transaction.Begin() || |
| 1141 !CreateTable(db_.get(), kTables[3])) { |
| 1142 return false; |
| 1143 } |
| 1144 |
| 1145 // Move data from the old table to the new table, setting the |
| 1146 // 'type' for all current records to the value for FALLBACK_NAMESPACE. |
| 1147 DCHECK_EQ(0, static_cast<int>(FALLBACK_NAMESPACE)); |
| 1148 if (!db_->Execute( |
| 1149 "INSERT INTO Namespaces" |
| 1150 " SELECT cache_id, origin, 0, namespace_url, fallback_entry_url" |
| 1151 " FROM FallbackNameSpaces")) { |
| 1152 return false; |
| 1153 } |
| 1154 |
| 1155 // Drop the old table, indexes on that table are also removed by this. |
| 1156 if (!db_->Execute("DROP TABLE FallbackNameSpaces")) |
| 1157 return false; |
| 1158 |
| 1159 // Create new indexes. |
| 1160 if (!CreateIndex(db_.get(), kIndexes[6]) || |
| 1161 !CreateIndex(db_.get(), kIndexes[7]) || |
| 1162 !CreateIndex(db_.get(), kIndexes[8])) { |
| 1163 return false; |
| 1164 } |
| 1165 |
| 1166 // Finally bump the version numbers and commit it. |
| 1167 meta_table_->SetVersionNumber(4); |
| 1168 meta_table_->SetCompatibleVersionNumber(4); |
| 1169 return transaction.Commit(); |
| 1170 } |
1103 | 1171 |
1104 // If there is no upgrade path for the version on disk to the current | 1172 // If there is no upgrade path for the version on disk to the current |
1105 // version, nuke everything and start over. | 1173 // version, nuke everything and start over. |
1106 return DeleteExistingAndCreateNewDatabase(); | 1174 return DeleteExistingAndCreateNewDatabase(); |
1107 } | 1175 } |
1108 | 1176 |
1109 void AppCacheDatabase::ResetConnectionAndTables() { | 1177 void AppCacheDatabase::ResetConnectionAndTables() { |
1110 meta_table_.reset(); | 1178 meta_table_.reset(); |
1111 db_.reset(); | 1179 db_.reset(); |
1112 } | 1180 } |
(...skipping 18 matching lines...) Expand all Loading... |
1131 | 1199 |
1132 // So we can't go recursive. | 1200 // So we can't go recursive. |
1133 if (is_recreating_) | 1201 if (is_recreating_) |
1134 return false; | 1202 return false; |
1135 | 1203 |
1136 AutoReset<bool> auto_reset(&is_recreating_, true); | 1204 AutoReset<bool> auto_reset(&is_recreating_, true); |
1137 return LazyOpen(true); | 1205 return LazyOpen(true); |
1138 } | 1206 } |
1139 | 1207 |
1140 } // namespace appcache | 1208 } // namespace appcache |
OLD | NEW |