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

Side by Side Diff: WebCore/storage/IDBFactoryBackendImpl.cpp

Issue 5800002: Merge 73697 - 2010-12-10 Hans Wennborg <hans@chromium.org>... (Closed) Base URL: http://svn.webkit.org/repository/webkit/branches/chromium/597/
Patch Set: Created 10 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « WebCore/bindings/v8/custom/V8IDBKeyCustom.cpp ('k') | WebCore/storage/IDBKey.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright (C) 2010 Google Inc. All rights reserved. 2 * Copyright (C) 2010 Google Inc. All rights reserved.
3 * 3 *
4 * Redistribution and use in source and binary forms, with or without 4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions 5 * modification, are permitted provided that the following conditions
6 * are met: 6 * are met:
7 * 7 *
8 * 1. Redistributions of source code must retain the above copyright 8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer. 9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright 10 * 2. Redistributions in binary form must reproduce the above copyright
(...skipping 17 matching lines...) Expand all
28 28
29 #include "config.h" 29 #include "config.h"
30 #include "IDBFactoryBackendImpl.h" 30 #include "IDBFactoryBackendImpl.h"
31 31
32 #include "DOMStringList.h" 32 #include "DOMStringList.h"
33 #include "FileSystem.h" 33 #include "FileSystem.h"
34 #include "IDBDatabaseBackendImpl.h" 34 #include "IDBDatabaseBackendImpl.h"
35 #include "IDBDatabaseException.h" 35 #include "IDBDatabaseException.h"
36 #include "IDBSQLiteDatabase.h" 36 #include "IDBSQLiteDatabase.h"
37 #include "IDBTransactionCoordinator.h" 37 #include "IDBTransactionCoordinator.h"
38 #include "SQLiteStatement.h"
39 #include "SQLiteTransaction.h"
38 #include "SecurityOrigin.h" 40 #include "SecurityOrigin.h"
39 #include <wtf/Threading.h> 41 #include <wtf/Threading.h>
40 #include <wtf/UnusedParam.h> 42 #include <wtf/UnusedParam.h>
41 43
42 #if ENABLE(INDEXED_DATABASE) 44 #if ENABLE(INDEXED_DATABASE)
43 45
44 namespace WebCore { 46 namespace WebCore {
45 47
46 IDBFactoryBackendImpl::IDBFactoryBackendImpl() 48 IDBFactoryBackendImpl::IDBFactoryBackendImpl()
47 : m_transactionCoordinator(IDBTransactionCoordinator::create()) 49 : m_transactionCoordinator(IDBTransactionCoordinator::create())
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
86 88
87 // FIXME: Error checking? 89 // FIXME: Error checking?
88 sqliteDatabase->db().setMaximumSize(maximumSize); 90 sqliteDatabase->db().setMaximumSize(maximumSize);
89 sqliteDatabase->db().turnOnIncrementalAutoVacuum(); 91 sqliteDatabase->db().turnOnIncrementalAutoVacuum();
90 92
91 return sqliteDatabase.release(); 93 return sqliteDatabase.release();
92 } 94 }
93 95
94 static bool createTables(SQLiteDatabase& sqliteDatabase) 96 static bool createTables(SQLiteDatabase& sqliteDatabase)
95 { 97 {
98 if (sqliteDatabase.tableExists("Databases"))
99 return true;
100
96 static const char* commands[] = { 101 static const char* commands[] = {
97 "CREATE TABLE IF NOT EXISTS Databases (id INTEGER PRIMARY KEY, name TEXT NOT NULL, description TEXT NOT NULL, version TEXT NOT NULL)", 102 "CREATE TABLE Databases (id INTEGER PRIMARY KEY, name TEXT NOT NULL, des cription TEXT NOT NULL, version TEXT NOT NULL)",
98 "CREATE UNIQUE INDEX IF NOT EXISTS Databases_name ON Databases(name)", 103 "CREATE UNIQUE INDEX Databases_name ON Databases(name)",
99 104
100 "CREATE TABLE IF NOT EXISTS ObjectStores (id INTEGER PRIMARY KEY, name T EXT NOT NULL, keyPath TEXT, doAutoIncrement INTEGER NOT NULL, databaseId INTEGER NOT NULL REFERENCES Databases(id))", 105 "CREATE TABLE ObjectStores (id INTEGER PRIMARY KEY, name TEXT NOT NULL, keyPath TEXT, doAutoIncrement INTEGER NOT NULL, databaseId INTEGER NOT NULL REFE RENCES Databases(id))",
101 "CREATE UNIQUE INDEX IF NOT EXISTS ObjectStores_composit ON ObjectStores (databaseId, name)", 106 "CREATE UNIQUE INDEX ObjectStores_composit ON ObjectStores(databaseId, n ame)",
102 107
103 "CREATE TABLE IF NOT EXISTS Indexes (id INTEGER PRIMARY KEY, objectStore Id INTEGER NOT NULL REFERENCES ObjectStore(id), name TEXT NOT NULL, keyPath TEXT , isUnique INTEGER NOT NULL)", 108 "CREATE TABLE Indexes (id INTEGER PRIMARY KEY, objectStoreId INTEGER NOT NULL REFERENCES ObjectStore(id), name TEXT NOT NULL, keyPath TEXT, isUnique INT EGER NOT NULL)",
104 "CREATE UNIQUE INDEX IF NOT EXISTS Indexes_composit ON Indexes(objectSto reId, name)", 109 "CREATE UNIQUE INDEX Indexes_composit ON Indexes(objectStoreId, name)",
105 110
106 "CREATE TABLE IF NOT EXISTS ObjectStoreData (id INTEGER PRIMARY KEY, obj ectStoreId INTEGER NOT NULL REFERENCES ObjectStore(id), keyString TEXT, keyDate INTEGER, keyNumber INTEGER, value TEXT NOT NULL)", 111 "CREATE TABLE ObjectStoreData (id INTEGER PRIMARY KEY, objectStoreId INT EGER NOT NULL REFERENCES ObjectStore(id), keyString TEXT, keyDate INTEGER, keyNu mber INTEGER, value TEXT NOT NULL)",
107 "CREATE UNIQUE INDEX IF NOT EXISTS ObjectStoreData_composit ON ObjectSto reData(keyString, keyDate, keyNumber, objectStoreId)", 112 "CREATE UNIQUE INDEX ObjectStoreData_composit ON ObjectStoreData(keyStri ng, keyDate, keyNumber, objectStoreId)",
108 113
109 "CREATE TABLE IF NOT EXISTS IndexData (id INTEGER PRIMARY KEY, indexId I NTEGER NOT NULL REFERENCES Indexes(id), keyString TEXT, keyDate INTEGER, keyNumb er INTEGER, objectStoreDataId INTEGER NOT NULL REFERENCES ObjectStoreData(id))", 114 "CREATE TABLE IndexData (id INTEGER PRIMARY KEY, indexId INTEGER NOT NUL L REFERENCES Indexes(id), keyString TEXT, keyDate INTEGER, keyNumber INTEGER, ob jectStoreDataId INTEGER NOT NULL REFERENCES ObjectStoreData(id))",
110 "CREATE INDEX IF NOT EXISTS IndexData_composit ON IndexData(keyString, k eyDate, keyNumber, indexId)", 115 "CREATE INDEX IndexData_composit ON IndexData(keyString, keyDate, keyNum ber, indexId)",
111 "CREATE INDEX IF NOT EXISTS IndexData_objectStoreDataId ON IndexData(obj ectStoreDataId)", 116 "CREATE INDEX IndexData_objectStoreDataId ON IndexData(objectStoreDataId )",
112 "CREATE INDEX IF NOT EXISTS IndexData_indexId ON IndexData(indexId)" 117 "CREATE INDEX IndexData_indexId ON IndexData(indexId)",
113 }; 118 };
114 119
120 SQLiteTransaction transaction(sqliteDatabase, false);
121 transaction.begin();
115 for (size_t i = 0; i < arraysize(commands); ++i) { 122 for (size_t i = 0; i < arraysize(commands); ++i) {
116 if (!sqliteDatabase.executeCommand(commands[i])) { 123 if (!sqliteDatabase.executeCommand(commands[i])) {
117 // FIXME: We should try to recover from this situation. Maybe nuke t he database and start over? 124 // FIXME: We should try to recover from this situation. Maybe nuke t he database and start over?
118 LOG_ERROR("Failed to run the following command for IndexedDB: %s", c ommands[i]); 125 LOG_ERROR("Failed to run the following command for IndexedDB: %s", c ommands[i]);
119 return false; 126 return false;
120 } 127 }
121 } 128 }
129 transaction.commit();
130 return true;
131 }
132
133 static bool createMetaDataTable(SQLiteDatabase& sqliteDatabase)
134 {
135 static const char* commands[] = {
136 "CREATE TABLE MetaData (name TEXT PRIMARY KEY, value NONE)",
137 "INSERT INTO MetaData VALUES ('version', 1)",
138 };
139
140 SQLiteTransaction transaction(sqliteDatabase, false);
141 transaction.begin();
142 for (size_t i = 0; i < arraysize(commands); ++i) {
143 if (!sqliteDatabase.executeCommand(commands[i]))
144 return false;
145 }
146 transaction.commit();
147 return true;
148 }
149
150 static bool getDatabaseVersion(SQLiteDatabase& sqliteDatabase, int* databaseVers ion)
151 {
152 SQLiteStatement query(sqliteDatabase, "SELECT value FROM MetaData WHERE name = 'version'");
153 if (query.prepare() != SQLResultOk || query.step() != SQLResultRow)
154 return false;
155
156 *databaseVersion = query.getColumnInt(0);
157 return query.finalize() == SQLResultOk;
158 }
159
160 static bool migrateDatabase(SQLiteDatabase& sqliteDatabase)
161 {
162 if (!sqliteDatabase.tableExists("MetaData")) {
163 if (!createMetaDataTable(sqliteDatabase))
164 return false;
165 }
166
167 int databaseVersion;
168 if (!getDatabaseVersion(sqliteDatabase, &databaseVersion))
169 return false;
170
171 if (databaseVersion == 1) {
172 static const char* commands[] = {
173 "DROP TABLE IF EXISTS ObjectStoreData2",
174 "CREATE TABLE ObjectStoreData2 (id INTEGER PRIMARY KEY, objectStoreI d INTEGER NOT NULL REFERENCES ObjectStore(id), keyString TEXT, keyDate REAL, key Number REAL, value TEXT NOT NULL)",
175 "INSERT INTO ObjectStoreData2 SELECT * FROM ObjectStoreData",
176 "DROP TABLE ObjectStoreData", // This depends on SQLite not enforcin g referential consistency.
177 "ALTER TABLE ObjectStoreData2 RENAME TO ObjectStoreData",
178 "CREATE UNIQUE INDEX ObjectStoreData_composit ON ObjectStoreData(key String, keyDate, keyNumber, objectStoreId)",
179 "DROP TABLE IF EXISTS IndexData2", // This depends on SQLite not enf orcing referential consistency.
180 "CREATE TABLE IndexData2 (id INTEGER PRIMARY KEY, indexId INTEGER NO T NULL REFERENCES Indexes(id), keyString TEXT, keyDate REAL, keyNumber REAL, obj ectStoreDataId INTEGER NOT NULL REFERENCES ObjectStoreData(id))",
181 "INSERT INTO IndexData2 SELECT * FROM IndexData",
182 "DROP TABLE IndexData",
183 "ALTER TABLE IndexData2 RENAME TO IndexData",
184 "CREATE INDEX IndexData_composit ON IndexData(keyString, keyDate, ke yNumber, indexId)",
185 "CREATE INDEX IndexData_objectStoreDataId ON IndexData(objectStoreDa taId)",
186 "CREATE INDEX IndexData_indexId ON IndexData(indexId)",
187 "UPDATE MetaData SET value = 2 WHERE name = 'version'",
188 };
189
190 SQLiteTransaction transaction(sqliteDatabase, false);
191 transaction.begin();
192 for (size_t i = 0; i < arraysize(commands); ++i) {
193 if (!sqliteDatabase.executeCommand(commands[i])) {
194 LOG_ERROR("Failed to run the following command for IndexedDB: %s ", commands[i]);
195 return false;
196 }
197 }
198 transaction.commit();
199
200 databaseVersion = 2;
201 }
202
122 return true; 203 return true;
123 } 204 }
124 205
125 void IDBFactoryBackendImpl::open(const String& name, PassRefPtr<IDBCallbacks> ca llbacks, PassRefPtr<SecurityOrigin> securityOrigin, Frame*, const String& dataDi r, int64_t maximumSize) 206 void IDBFactoryBackendImpl::open(const String& name, PassRefPtr<IDBCallbacks> ca llbacks, PassRefPtr<SecurityOrigin> securityOrigin, Frame*, const String& dataDi r, int64_t maximumSize)
126 { 207 {
127 String fileIdentifier = securityOrigin->databaseIdentifier(); 208 String fileIdentifier = securityOrigin->databaseIdentifier();
128 String uniqueIdentifier = fileIdentifier + "@" + name; 209 String uniqueIdentifier = fileIdentifier + "@" + name;
129 IDBDatabaseBackendMap::iterator it = m_databaseBackendMap.find(uniqueIdentif ier); 210 IDBDatabaseBackendMap::iterator it = m_databaseBackendMap.find(uniqueIdentif ier);
130 if (it != m_databaseBackendMap.end()) { 211 if (it != m_databaseBackendMap.end()) {
131 callbacks->onSuccess(it->second); 212 callbacks->onSuccess(it->second);
132 return; 213 return;
133 } 214 }
134 215
135 // FIXME: Everything from now on should be done on another thread. 216 // FIXME: Everything from now on should be done on another thread.
136 217
137 RefPtr<IDBSQLiteDatabase> sqliteDatabase; 218 RefPtr<IDBSQLiteDatabase> sqliteDatabase;
138 SQLiteDatabaseMap::iterator it2 = m_sqliteDatabaseMap.find(fileIdentifier); 219 SQLiteDatabaseMap::iterator it2 = m_sqliteDatabaseMap.find(fileIdentifier);
139 if (it2 != m_sqliteDatabaseMap.end()) 220 if (it2 != m_sqliteDatabaseMap.end())
140 sqliteDatabase = it2->second; 221 sqliteDatabase = it2->second;
141 else { 222 else {
142 sqliteDatabase = openSQLiteDatabase(securityOrigin.get(), dataDir, maxim umSize, fileIdentifier, this); 223 sqliteDatabase = openSQLiteDatabase(securityOrigin.get(), dataDir, maxim umSize, fileIdentifier, this);
143 224
144 if (!sqliteDatabase || !createTables(sqliteDatabase->db())) { 225 if (!sqliteDatabase || !createTables(sqliteDatabase->db()) || !migrateDa tabase(sqliteDatabase->db())) {
145 callbacks->onError(IDBDatabaseError::create(IDBDatabaseException::UN KNOWN_ERR, "Internal error.")); 226 callbacks->onError(IDBDatabaseError::create(IDBDatabaseException::UN KNOWN_ERR, "Internal error."));
227 m_sqliteDatabaseMap.set(fileIdentifier, 0);
146 return; 228 return;
147 } 229 }
148 m_sqliteDatabaseMap.set(fileIdentifier, sqliteDatabase.get()); 230 m_sqliteDatabaseMap.set(fileIdentifier, sqliteDatabase.get());
149 } 231 }
150 232
151 RefPtr<IDBDatabaseBackendImpl> databaseBackend = IDBDatabaseBackendImpl::cre ate(name, sqliteDatabase.get(), m_transactionCoordinator.get(), this, uniqueIden tifier); 233 RefPtr<IDBDatabaseBackendImpl> databaseBackend = IDBDatabaseBackendImpl::cre ate(name, sqliteDatabase.get(), m_transactionCoordinator.get(), this, uniqueIden tifier);
152 callbacks->onSuccess(databaseBackend.get()); 234 callbacks->onSuccess(databaseBackend.get());
153 m_databaseBackendMap.set(uniqueIdentifier, databaseBackend.get()); 235 m_databaseBackendMap.set(uniqueIdentifier, databaseBackend.get());
154 } 236 }
155 237
156 } // namespace WebCore 238 } // namespace WebCore
157 239
158 #endif // ENABLE(INDEXED_DATABASE) 240 #endif // ENABLE(INDEXED_DATABASE)
159
OLDNEW
« no previous file with comments | « WebCore/bindings/v8/custom/V8IDBKeyCustom.cpp ('k') | WebCore/storage/IDBKey.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698