Changeset 91060 in webkit
- Timestamp:
- Jul 15, 2011 1:35:16 AM (13 years ago)
- Location:
- trunk/Source/WebCore
- Files:
-
- 1 added
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WebCore/ChangeLog
r91058 r91060 1 2011-07-15 Jonathan Dong <jonathan.dong@torchmobile.com.cn> 2 3 LocalStorage: Changed the value type of ItemTable from TEXT to BLOB 4 to avoid string truncation. 5 This patch will also convert the exsisting ItemTable and perform 6 the DATA MIGRATION job. 7 https://bugs.webkit.org/show_bug.cgi?id=58762 8 9 Reviewed by Jeremy Orlow. 10 11 Tests: manual-tests/localstorage-value-truncation.html 12 13 * manual-tests/localstorage-value-truncation.html: Added. 14 Demostrate the testcase shown in bug 58762. 15 * platform/sql/SQLiteStatement.cpp: 16 (WebCore::SQLiteStatement::isColumnDeclearedAsBlob): 17 Test if the pre-defined type of column is BLOB. 18 * platform/sql/SQLiteStatement.h: 19 * storage/StorageAreaSync.cpp: 20 Change the localStorage value type from Text to BLOB to avoid the 21 value string truncation at \x00. 22 (WebCore::StorageAreaSync::openDatabase): 23 Change the database structure, use BLOB to replace the TEXT type of 24 value segment in ItemTable. 25 (WebCore::StorageAreaSync::migrateItemTableIfNeeded): 26 Migrate the ItemTable if the pre-defined type of value is TEXT. 27 (WebCore::StorageAreaSync::performImport): 28 Use getColumnBlobAsString() to import the BLOB value. 29 (WebCore::StorageAreaSync::sync): 30 Use bindBlob() to bind value string to the SQLiteStatement for the 31 database execution. 32 * storage/StorageAreaSync.h: 33 1 34 2011-07-15 Kentaro Hara <haraken@google.com> 2 35 -
trunk/Source/WebCore/platform/sql/SQLiteStatement.cpp
r76448 r91060 288 288 } 289 289 290 bool SQLiteStatement::isColumnDeclaredAsBlob(int col) 291 { 292 ASSERT(col >= 0); 293 if (!m_statement) { 294 if (prepare() != SQLITE_OK) 295 return false; 296 } 297 298 return equalIgnoringCase(String("BLOB"), String(reinterpret_cast<const UChar*>(sqlite3_column_decltype16(m_statement, col)))); 299 } 300 290 301 String SQLiteStatement::getColumnName(int col) 291 302 { -
trunk/Source/WebCore/platform/sql/SQLiteStatement.h
r76448 r91060 75 75 76 76 bool isColumnNull(int col); 77 bool isColumnDeclaredAsBlob(int col); 77 78 String getColumnName(int col); 78 79 SQLValue getColumnValue(int col); -
trunk/Source/WebCore/storage/StorageAreaSync.cpp
r81037 r91060 34 34 #include "SQLiteFileSystem.h" 35 35 #include "SQLiteStatement.h" 36 #include "SQLiteTransaction.h" 36 37 #include "SecurityOrigin.h" 37 38 #include "StorageAreaImpl.h" … … 255 256 } 256 257 257 if (!m_database.executeCommand("CREATE TABLE IF NOT EXISTS ItemTable (key TEXT UNIQUE ON CONFLICT REPLACE, value TEXT NOT NULL ON CONFLICT FAIL)")) { 258 migrateItemTableIfNeeded(); 259 260 if (!m_database.executeCommand("CREATE TABLE IF NOT EXISTS ItemTable (key TEXT UNIQUE ON CONFLICT REPLACE, value BLOB NOT NULL ON CONFLICT FAIL)")) { 258 261 LOG_ERROR("Failed to create table ItemTable for local storage"); 259 262 markImported(); … … 263 266 264 267 StorageTracker::tracker().setOriginDetails(m_databaseIdentifier, databaseFilename); 268 } 269 270 void StorageAreaSync::migrateItemTableIfNeeded() 271 { 272 if (!m_database.tableExists("ItemTable")) 273 return; 274 275 { 276 SQLiteStatement query(m_database, "SELECT value FROM ItemTable LIMIT 1"); 277 // this query isn't ever executed. 278 if (query.isColumnDeclaredAsBlob(0)) 279 return; 280 } 281 282 // alter table for backward compliance, change the value type from TEXT to BLOB. 283 static const char* commands[] = { 284 "DROP TABLE IF EXISTS ItemTable2", 285 "CREATE TABLE ItemTable2 (key TEXT UNIQUE ON CONFLICT REPLACE, value BLOB NOT NULL ON CONFLICT FAIL)", 286 "INSERT INTO ItemTable2 SELECT * from ItemTable", 287 "DROP TABLE ItemTable", 288 "ALTER TABLE ItemTable2 RENAME TO ItemTable", 289 0, 290 }; 291 292 SQLiteTransaction transaction(m_database, false); 293 transaction.begin(); 294 for (size_t i = 0; commands[i]; ++i) { 295 if (!m_database.executeCommand(commands[i])) { 296 LOG_ERROR("Failed to migrate table ItemTable for local storage when executing: %s", commands[i]); 297 transaction.rollback(); 298 299 // finally it will try to keep a backup of ItemTable for the future restoration. 300 // NOTICE: this will essentially DELETE the current database, but that's better 301 // than continually hitting this case and never being able to use the local storage. 302 // if this is ever hit, it's definitely a bug. 303 ASSERT_NOT_REACHED(); 304 if (!m_database.executeCommand("ALTER TABLE ItemTable RENAME TO Backup_ItemTable")) 305 LOG_ERROR("Failed to save ItemTable after migration job failed."); 306 307 return; 308 } 309 } 310 transaction.commit(); 265 311 } 266 312 … … 287 333 int result = query.step(); 288 334 while (result == SQLResultRow) { 289 itemMap.set(query.getColumnText(0), query.getColumn Text(1));335 itemMap.set(query.getColumnText(0), query.getColumnBlobAsString(1)); 290 336 result = query.step(); 291 337 } … … 393 439 // If the second argument is non-null, we're doing an insert, so bind it as the value. 394 440 if (!it->second.isNull()) 395 query.bind Text(2, it->second);441 query.bindBlob(2, it->second); 396 442 397 443 int result = query.step(); -
trunk/Source/WebCore/storage/StorageAreaSync.h
r80892 r91060 103 103 mutable bool m_importComplete; 104 104 void markImported(); 105 void migrateItemTableIfNeeded(); 105 106 }; 106 107
Note: See TracChangeset
for help on using the changeset viewer.