Changeset 66820 in webkit
- Timestamp:
- Sep 6, 2010 3:33:31 AM (14 years ago)
- Location:
- trunk
- Files:
-
- 16 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/LayoutTests/ChangeLog
r66817 r66820 1 2010-08-26 Jeremy Orlow <jorlow@chromium.org> 2 3 Reviewed by Steve Block. 4 5 Add index insertion support to IndexedDB. 6 https://bugs.webkit.org/show_bug.cgi?id=44695 7 8 * storage/indexeddb/objectstore-basics-expected.txt: 9 * storage/indexeddb/script-tests/objectstore-basics.js: 10 (createSuccess): 11 (addIndexSuccess): 12 (getSuccess): 13 1 14 2010-09-06 Philippe Normand <pnormand@igalia.com> 2 15 -
trunk/LayoutTests/storage/indexeddb/objectstore-basics-expected.txt
r64214 r66820 51 51 PASS storeNames.contains('storeName') is true 52 52 PASS storeNames.length is 1 53 store.add('value', 'key') 53 event.result.createIndex('indexName', 'x') 54 PASS 'onsuccess' in result is true 55 PASS 'onerror' in result is true 56 PASS 'abort' in result is true 57 PASS 'readyState' in result is true 58 An event should fire shortly... 59 60 addIndexSuccess(): 61 Success event fired: 62 PASS 'result' in event is true 63 PASS 'code' in event is false 64 PASS 'message' in event is false 65 PASS 'source' in event is true 66 PASS event.source != null is true 67 PASS 'onsuccess' in event.target is true 68 PASS 'onerror' in event.target is true 69 PASS 'abort' in event.target is true 70 PASS 'readyState' in event.target is true 71 PASS event.target.readyState is event.target.DONE 72 73 PASS event.source.indexNames.contains('indexName') is true 74 event.source.add({x: 'value'}, 'key') 54 75 PASS 'onsuccess' in result is true 55 76 PASS 'onerror' in result is true … … 93 114 PASS event.target.readyState is event.target.DONE 94 115 95 PASS event.result is "value"116 PASS event.result.x is "value" 96 117 store = event.source 97 118 store.remove('key') … … 119 140 120 141 TEST COMPLETE 142 -
trunk/LayoutTests/storage/indexeddb/script-tests/objectstore-basics.js
r65667 r66820 36 36 shouldBe("storeNames.contains('storeName')", "true"); 37 37 shouldBe("storeNames.length", "1"); 38 // FIXME: test store.indexNames, as well as allobject store's methods.38 // FIXME: test all of object store's methods. 39 39 40 result = evalAndLog("store.add('value', 'key')"); 40 result = evalAndLog("event.result.createIndex('indexName', 'x')"); 41 verifyResult(result); 42 result.onsuccess = addIndexSuccess; 43 result.onerror = unexpectedErrorCallback; 44 } 45 46 function addIndexSuccess() 47 { 48 debug("addIndexSuccess():"); 49 verifySuccessEvent(event); 50 shouldBeTrue("event.source.indexNames.contains('indexName')"); 51 52 result = evalAndLog("event.source.add({x: 'value'}, 'key')"); 41 53 verifyResult(result); 42 54 result.onsuccess = addSuccess; … … 61 73 debug("getSuccess():"); 62 74 verifySuccessEvent(event); 63 shouldBeEqualToString("event.result ", "value");75 shouldBeEqualToString("event.result.x", "value"); 64 76 var store = evalAndLog("store = event.source"); 65 77 -
trunk/WebCore/ChangeLog
r66818 r66820 1 2010-08-26 Jeremy Orlow <jorlow@chromium.org> 2 3 Reviewed by Steve Block. 4 5 Add index insertion support to IndexedDB. 6 https://bugs.webkit.org/show_bug.cgi?id=44695 7 8 Whenever you insert an item into an ObjectStore, it should use all 9 indexes' key paths to insert corresponding entries into each index. 10 Also data should be deleted out of the index when it goes away. 11 12 Not much testing yet since there's no way to directly observe indexes. 13 More will be in next patch. 14 15 * storage/IDBDatabaseBackendImpl.cpp: 16 (WebCore::IDBDatabaseBackendImpl::removeObjectStore): 17 * storage/IDBFactoryBackendImpl.cpp: 18 (WebCore::createTables): 19 * storage/IDBIndex.idl: 20 * storage/IDBIndexBackendImpl.cpp: 21 (WebCore::whereClause): 22 (WebCore::bindWhereClause): 23 (WebCore::IDBIndexBackendImpl::addingKeyAllowed): 24 * storage/IDBIndexBackendImpl.h: 25 (WebCore::IDBIndexBackendImpl::id): 26 * storage/IDBKey.cpp: 27 (WebCore::IDBKey::whereSyntax): 28 (WebCore::IDBKey::bind): 29 (WebCore::IDBKey::bindWithNulls): 30 * storage/IDBKey.h: 31 * storage/IDBObjectStore.idl: 32 * storage/IDBObjectStoreBackendImpl.cpp: 33 (WebCore::whereClause): 34 (WebCore::bindWhereClause): 35 (WebCore::IDBObjectStoreBackendImpl::get): 36 (WebCore::fetchKeyFromKeyPath): 37 (WebCore::putObjectStoreData): 38 (WebCore::putIndexData): 39 (WebCore::IDBObjectStoreBackendImpl::put): 40 (WebCore::IDBObjectStoreBackendImpl::remove): 41 (WebCore::IDBObjectStoreBackendImpl::createIndex): 42 (WebCore::doDelete): 43 (WebCore::IDBObjectStoreBackendImpl::removeIndex): 44 (WebCore::IDBObjectStoreBackendImpl::openCursor): 45 * storage/IDBObjectStoreBackendImpl.h: 46 1 47 2010-09-06 Anton Muhin <antonm@chromium.org> 2 48 -
trunk/WebCore/storage/IDBDatabaseBackendImpl.cpp
r66216 r66820 178 178 doDelete(sqliteDatabase(), "DELETE FROM ObjectStores WHERE id = ?", objectStore->id()); 179 179 doDelete(sqliteDatabase(), "DELETE FROM ObjectStoreData WHERE objectStoreId = ?", objectStore->id()); 180 doDelete(sqliteDatabase(), "DELETE FROM IndexData WHERE indexId IN (SELECT id FROM Indexes WHERE objectStoreId = ?)", objectStore->id()); 180 181 doDelete(sqliteDatabase(), "DELETE FROM Indexes WHERE objectStoreId = ?", objectStore->id()); 181 // FIXME: Delete index data as well.182 182 transaction.commit(); 183 183 -
trunk/WebCore/storage/IDBFactoryBackendImpl.cpp
r65902 r66820 84 84 85 85 "DROP TABLE IF EXISTS ObjectStores", 86 "CREATE TABLE IF NOT EXISTS ObjectStores (id INTEGER PRIMARY KEY, name TEXT NOT NULL , keyPath TEXT, doAutoIncrement INTEGER NOT NULL)",86 "CREATE TABLE IF NOT EXISTS ObjectStores (id INTEGER PRIMARY KEY, name TEXT NOT NULL UNIQUE, keyPath TEXT, doAutoIncrement INTEGER NOT NULL)", 87 87 "DROP INDEX IF EXISTS ObjectStores_name", 88 88 "CREATE UNIQUE INDEX IF NOT EXISTS ObjectStores_name ON ObjectStores(name)", 89 89 90 90 "DROP TABLE IF EXISTS Indexes", 91 "CREATE TABLE IF NOT EXISTS Indexes (id INTEGER PRIMARY KEY, objectStoreId INTEGER NOT NULL REFERENCES ObjectStore(id), name TEXT NOT NULL , keyPath TEXT, isUnique INTEGER NOT NULL)",91 "CREATE TABLE IF NOT EXISTS Indexes (id INTEGER PRIMARY KEY, objectStoreId INTEGER NOT NULL REFERENCES ObjectStore(id), name TEXT NOT NULL UNIQUE, keyPath TEXT, isUnique INTEGER NOT NULL)", 92 92 "DROP INDEX IF EXISTS Indexes_composit", 93 93 "CREATE UNIQUE INDEX IF NOT EXISTS Indexes_composit ON Indexes(objectStoreId, name)", 94 94 95 95 "DROP TABLE IF EXISTS ObjectStoreData", 96 "CREATE TABLE IF NOT EXISTS ObjectStoreData (id INTEGER PRIMARY KEY, objectStoreId INTEGER NOT NULL REFERENCES ObjectStore(id), keyString TEXT , keyDate INTEGER, keyNumber INTEGER, value TEXT NOT NULL)",96 "CREATE TABLE IF NOT EXISTS ObjectStoreData (id INTEGER PRIMARY KEY, objectStoreId INTEGER NOT NULL REFERENCES ObjectStore(id), keyString TEXT UNIQUE, keyDate INTEGER UNIQUE, keyNumber INTEGER UNIQUE, value TEXT NOT NULL)", 97 97 "DROP INDEX IF EXISTS ObjectStoreData_composit", 98 "CREATE UNIQUE INDEX IF NOT EXISTS ObjectStoreData_composit ON ObjectStoreData(keyString, keyDate, keyNumber, objectStoreId)" 98 "CREATE UNIQUE INDEX IF NOT EXISTS ObjectStoreData_composit ON ObjectStoreData(keyString, keyDate, keyNumber, objectStoreId)", 99 100 "DROP TABLE IF EXISTS IndexData", 101 "CREATE TABLE IF NOT EXISTS IndexData (id INTEGER PRIMARY KEY, indexId INTEGER NOT NULL REFERENCES Indexs(id), keyString TEXT, keyDate INTEGER, keyNumber INTEGER, objectStoreDataId INTEGER NOT NULL UNIQUE REFERENCES ObjectStoreData(id))", 102 "DROP INDEX IF EXISTS IndexData_composit", 103 "CREATE UNIQUE INDEX IF NOT EXISTS IndexData_composit ON IndexData(keyString, keyDate, keyNumber, indexId)", 104 "DROP INDEX IF EXISTS IndexData_objectStoreDataId", 105 "CREATE UNIQUE INDEX IF NOT EXISTS IndexData_objectStoreDataId ON IndexData(objectStoreDataId)", 106 "DROP INDEX IF EXISTS IndexData_indexId", 107 "CREATE UNIQUE INDEX IF NOT EXISTS IndexData_indexId ON IndexData(indexId)" 99 108 }; 100 109 -
trunk/WebCore/storage/IDBIndex.idl
r64358 r66820 29 29 Conditional=INDEXED_DATABASE 30 30 ] IDBIndex { 31 // FIXME: Complete this file.32 33 31 readonly attribute DOMString name; 32 // FIXME: Add "storeName". 34 33 readonly attribute DOMString keyPath; 35 34 readonly attribute boolean unique; 35 36 // FIXME: Implement. 37 //IDBRequest openObjectCursor(in [Optional] IDBKeyRange range, in [Optional] unsigned short direction) raises (DOMException); 38 //IDBRequest openCursor(in [Optional] IDBKeyRange range, in [Optional] unsigned short direction) raises (DOMException); 39 //IDBRequest getObject(in IDBKey key) raises (DOMException); 40 //IDBRequest get(in IDBKey key) raises (DOMException); 36 41 }; 37 42 -
trunk/WebCore/storage/IDBIndexBackendImpl.cpp
r65667 r66820 31 31 #include "IDBDatabaseBackendImpl.h" 32 32 #include "IDBObjectStoreBackendImpl.h" 33 #include "SQLite Database.h"33 #include "SQLiteStatement.h" 34 34 35 35 namespace WebCore { … … 48 48 } 49 49 50 static String whereClause(IDBKey* key) 51 { 52 return "WHERE indexId = ? AND " + key->whereSyntax(); 53 } 54 55 static void bindWhereClause(SQLiteStatement& query, int64_t id, IDBKey* key) 56 { 57 query.bindInt64(1, id); 58 key->bind(query, 2); 59 } 60 61 bool IDBIndexBackendImpl::addingKeyAllowed(IDBKey* key) 62 { 63 if (!m_unique) 64 return true; 65 66 SQLiteStatement query(sqliteDatabase(), "SELECT id FROM IndexData " + whereClause(key)); 67 bool ok = query.prepare() == SQLResultOk; 68 ASSERT_UNUSED(ok, ok); // FIXME: Better error handling? 69 bindWhereClause(query, m_id, key); 70 bool existingValue = query.step() == SQLResultRow; 71 72 return !existingValue; 73 } 74 50 75 SQLiteDatabase& IDBIndexBackendImpl::sqliteDatabase() const 51 76 { -
trunk/WebCore/storage/IDBIndexBackendImpl.h
r65667 r66820 33 33 namespace WebCore { 34 34 35 class IDBKey; 35 36 class IDBObjectStoreBackendImpl; 36 37 class SQLiteDatabase; … … 43 44 } 44 45 virtual ~IDBIndexBackendImpl(); 46 47 int64_t id() { return m_id; } 48 bool addingKeyAllowed(IDBKey*); 45 49 46 50 // Implements IDBIndexBackendInterface. -
trunk/WebCore/storage/IDBKey.cpp
r66473 r66820 29 29 #if ENABLE(INDEXED_DATABASE) 30 30 31 #include "SQLiteStatement.h" 31 32 #include "SerializedScriptValue.h" 32 33 … … 73 74 } 74 75 76 String IDBKey::whereSyntax() const 77 { 78 switch (m_type) { 79 case IDBKey::StringType: 80 return "keyString = ?"; 81 case IDBKey::NumberType: 82 return "keyNumber = ?"; 83 // FIXME: Implement date. 84 case IDBKey::NullType: 85 return "keyString IS NULL AND keyDate IS NULL AND keyNumber IS NULL"; 86 } 87 88 ASSERT_NOT_REACHED(); 89 return ""; 90 } 91 92 // Returns the number of items bound. 93 int IDBKey::bind(SQLiteStatement& query, int column) const 94 { 95 switch (m_type) { 96 case IDBKey::StringType: 97 query.bindText(column, m_string); 98 return 1; 99 case IDBKey::NumberType: 100 query.bindInt(column, m_number); 101 return 1; 102 case IDBKey::NullType: 103 return 0; 104 } 105 106 ASSERT_NOT_REACHED(); 107 return 0; 108 } 109 110 void IDBKey::bindWithNulls(SQLiteStatement& query, int baseColumn) const 111 { 112 switch (m_type) { 113 case IDBKey::StringType: 114 query.bindText(baseColumn + 0, m_string); 115 query.bindNull(baseColumn + 1); 116 query.bindNull(baseColumn + 2); 117 break; 118 case IDBKey::NumberType: 119 query.bindNull(baseColumn + 0); 120 query.bindNull(baseColumn + 1); 121 query.bindInt(baseColumn + 2, m_number); 122 break; 123 case IDBKey::NullType: 124 query.bindNull(baseColumn + 0); 125 query.bindNull(baseColumn + 1); 126 query.bindNull(baseColumn + 2); 127 break; 128 default: 129 ASSERT_NOT_REACHED(); 130 } 131 } 132 75 133 } // namespace WebCore 76 134 -
trunk/WebCore/storage/IDBKey.h
r66473 r66820 33 33 34 34 namespace WebCore { 35 36 class SQLiteStatement; 35 37 36 38 // FIXME: Add dates. … … 73 75 74 76 bool isEqual(IDBKey* other); 77 String whereSyntax() const; 78 int bind(SQLiteStatement& query, int column) const; 79 void bindWithNulls(SQLiteStatement& query, int baseColumn) const; 75 80 76 81 private: -
trunk/WebCore/storage/IDBObjectStore.idl
r64828 r66820 29 29 Conditional=INDEXED_DATABASE 30 30 ] IDBObjectStore { 31 // FIXME: Many of these should raise on certain errors. 31 32 [CallWith=ScriptExecutionContext] IDBRequest get(in IDBKey key); 32 // FIXME: Come to concensus re getAll.33 // FIXME: SerializedScriptValue raises an exception if you pass in something that can't be serialized.34 // We need to instead "raise" this error via an error callback.35 33 [CallWith=ScriptExecutionContext] IDBRequest add(in SerializedScriptValue value, in [Optional] IDBKey key); 36 34 [CallWith=ScriptExecutionContext] IDBRequest put(in SerializedScriptValue value, in [Optional] IDBKey key); -
trunk/WebCore/storage/IDBObjectStoreBackendImpl.cpp
r66474 r66820 39 39 #include "SQLiteDatabase.h" 40 40 #include "SQLiteStatement.h" 41 #include "SQLiteTransaction.h" 41 42 42 43 #if ENABLE(INDEXED_DATABASE) … … 66 67 } 67 68 68 static String whereClause(IDBKey::Type type) 69 { 70 switch (type) { 71 case IDBKey::StringType: 72 return "WHERE objectStoreId = ? AND keyString = ?"; 73 case IDBKey::NumberType: 74 return "WHERE objectStoreId = ? AND keyNumber = ?"; 75 // FIXME: Implement date. 76 case IDBKey::NullType: 77 return "WHERE objectStoreId = ? AND keyString IS NULL AND keyDate IS NULL AND keyNumber IS NULL"; 78 } 79 80 ASSERT_NOT_REACHED(); 81 return ""; 82 } 83 84 // Returns number of items bound. 85 static int bindKey(SQLiteStatement& query, int column, IDBKey* key) 86 { 87 switch (key->type()) { 88 case IDBKey::StringType: 89 query.bindText(column, key->string()); 90 return 1; 91 case IDBKey::NumberType: 92 query.bindInt(column, key->number()); 93 return 1; 94 // FIXME: Implement date. 95 case IDBKey::NullType: 96 return 0; 97 } 98 99 ASSERT_NOT_REACHED(); 100 return 0; 69 static String whereClause(IDBKey* key) 70 { 71 return "WHERE objectStoreId = ? AND " + key->whereSyntax(); 101 72 } 102 73 … … 104 75 { 105 76 query.bindInt64(1, id); 106 bindKey(query, 2, key);77 key->bind(query, 2); 107 78 } 108 79 109 80 void IDBObjectStoreBackendImpl::get(PassRefPtr<IDBKey> key, PassRefPtr<IDBCallbacks> callbacks) 110 81 { 111 SQLiteStatement query(sqliteDatabase(), "SELECT keyString, keyDate, keyNumber, value FROM ObjectStoreData " + whereClause(key ->type()));82 SQLiteStatement query(sqliteDatabase(), "SELECT keyString, keyDate, keyNumber, value FROM ObjectStoreData " + whereClause(key.get())); 112 83 bool ok = query.prepare() == SQLResultOk; 113 84 ASSERT_UNUSED(ok, ok); // FIXME: Better error handling? … … 125 96 callbacks->onSuccess(SerializedScriptValue::createFromWire(query.getColumnText(3))); 126 97 ASSERT(query.step() != SQLResultRow); 98 } 99 100 static PassRefPtr<IDBKey> fetchKeyFromKeyPath(SerializedScriptValue* value, const String& keyPath) 101 { 102 Vector<RefPtr<SerializedScriptValue> > values; 103 values.append(value); 104 Vector<RefPtr<IDBKey> > keys; 105 IDBKeyPathBackendImpl::createIDBKeysFromSerializedValuesAndKeyPath(values, keyPath, keys); 106 if (keys.isEmpty()) 107 return 0; 108 ASSERT(keys.size() == 1); 109 return keys[0].release(); 110 } 111 112 static void putObjectStoreData(SQLiteDatabase& db, IDBKey* key, SerializedScriptValue* value, int64_t objectStoreId, int64_t* dataRowId) 113 { 114 String sql = *dataRowId != -1 ? "UPDATE ObjectStoreData SET keyString = ?, keyDate = ?, keyNumber = ?, value = ? WHERE id = ?" 115 : "INSERT INTO ObjectStoreData (keyString, keyDate, keyNumber, value, objectStoreId) VALUES (?, ?, ?, ?, ?)"; 116 SQLiteStatement query(db, sql); 117 bool ok = query.prepare() == SQLResultOk; 118 ASSERT_UNUSED(ok, ok); // FIXME: Better error handling? 119 key->bindWithNulls(query, 1); 120 query.bindText(4, value->toWireString()); 121 if (*dataRowId != -1) 122 query.bindInt(5, *dataRowId); 123 else 124 query.bindInt64(5, objectStoreId); 125 126 ok = query.step() == SQLResultDone; 127 ASSERT_UNUSED(ok, ok); // FIXME: Better error handling? 128 129 if (*dataRowId == -1) 130 *dataRowId = db.lastInsertRowID(); 131 } 132 133 static void putIndexData(SQLiteDatabase& db, IDBKey* key, int64_t indexId, int64_t objectStoreDataId) 134 { 135 SQLiteStatement deleteQuery(db, "DELETE FROM IndexData WHERE objectStoreDataId = ?"); 136 bool ok = deleteQuery.prepare() == SQLResultOk; 137 ASSERT_UNUSED(ok, ok); // FIXME: Better error handling. 138 deleteQuery.bindInt64(1, objectStoreDataId); 139 ok = deleteQuery.step() == SQLResultDone; 140 ASSERT_UNUSED(ok, ok); // FIXME: Better error handling. 141 142 SQLiteStatement putQuery(db, "INSERT INTO IndexData (keyString, keyDate, keyNumber, indexId, objectStoreDataId) VALUES (?, ?, ?, ?, ?)"); 143 ok = putQuery.prepare() == SQLResultOk; 144 ASSERT_UNUSED(ok, ok); // FIXME: Better error handling? 145 key->bindWithNulls(putQuery, 1); 146 putQuery.bindInt64(4, indexId); 147 putQuery.bindInt64(5, objectStoreDataId); 148 149 ok = putQuery.step() == SQLResultDone; 150 ASSERT_UNUSED(ok, ok); // FIXME: Better error handling? 127 151 } 128 152 … … 137 161 return; 138 162 } 139 Vector<RefPtr<SerializedScriptValue> > values; 140 values.append(value); 141 Vector<RefPtr<IDBKey> > idbKeys; 142 IDBKeyPathBackendImpl::createIDBKeysFromSerializedValuesAndKeyPath(values, m_keyPath, idbKeys); 143 if (idbKeys.isEmpty()) { 144 callbacks->onError(IDBDatabaseError::create(IDBDatabaseException::UNKNOWN_ERR, "An invalid keyPath was supplied for an objectStore.")); 163 key = fetchKeyFromKeyPath(value.get(), m_keyPath); 164 if (!key) { 165 callbacks->onError(IDBDatabaseError::create(IDBDatabaseException::UNKNOWN_ERR, "The key could not be fetched from the keyPath.")); 145 166 return; 146 167 } 147 key = idbKeys[0]; 148 } 149 150 if (!key) { 168 } else if (!key) { 151 169 callbacks->onError(IDBDatabaseError::create(IDBDatabaseException::DATA_ERR, "No key supplied.")); 152 170 return; 153 171 } 154 172 155 SQLiteStatement getQuery(sqliteDatabase(), "SELECT id FROM ObjectStoreData " + whereClause(key->type())); 173 Vector<RefPtr<IDBKey> > indexKeys; 174 for (IndexMap::iterator it = m_indexes.begin(); it != m_indexes.end(); ++it) { 175 RefPtr<IDBKey> key = fetchKeyFromKeyPath(value.get(), it->second->keyPath()); 176 if (!key) { 177 callbacks->onError(IDBDatabaseError::create(IDBDatabaseException::UNKNOWN_ERR, "The key could not be fetched from an index's keyPath.")); 178 return; 179 } 180 if (!it->second->addingKeyAllowed(key.get())) { 181 callbacks->onError(IDBDatabaseError::create(IDBDatabaseException::UNKNOWN_ERR, "One of the derived (from a keyPath) keys for an index does not satisfy its uniqueness requirements.")); 182 return; 183 } 184 indexKeys.append(key.release()); 185 } 186 187 SQLiteStatement getQuery(sqliteDatabase(), "SELECT id FROM ObjectStoreData " + whereClause(key.get())); 156 188 bool ok = getQuery.prepare() == SQLResultOk; 157 189 ASSERT_UNUSED(ok, ok); // FIXME: Better error handling? 158 190 159 191 bindWhereClause(getQuery, m_id, key.get()); 160 bool existingValue = getQuery.step() == SQLResultRow;161 if (addOnly && existingValue) {192 bool isExistingValue = getQuery.step() == SQLResultRow; 193 if (addOnly && isExistingValue) { 162 194 callbacks->onError(IDBDatabaseError::create(IDBDatabaseException::CONSTRAINT_ERR, "Key already exists in the object store.")); 163 195 return; 164 196 } 165 197 166 String sql = existingValue ? "UPDATE ObjectStoreData SET keyString = ?, keyDate = ?, keyNumber = ?, value = ? WHERE id = ?" 167 : "INSERT INTO ObjectStoreData (keyString, keyDate, keyNumber, value, objectStoreId) VALUES (?, ?, ?, ?, ?)"; 168 SQLiteStatement putQuery(sqliteDatabase(), sql); 169 ok = putQuery.prepare() == SQLResultOk; 170 ASSERT_UNUSED(ok, ok); // FIXME: Better error handling? 171 switch (key->type()) { 172 case IDBKey::StringType: 173 putQuery.bindText(1, key->string()); 174 putQuery.bindNull(2); 175 putQuery.bindNull(3); 176 break; 177 // FIXME: Implement date. 178 case IDBKey::NumberType: 179 putQuery.bindNull(1); 180 putQuery.bindNull(2); 181 putQuery.bindInt(3, key->number()); 182 break; 183 case IDBKey::NullType: 184 putQuery.bindNull(1); 185 putQuery.bindNull(2); 186 putQuery.bindNull(3); 187 break; 188 default: 189 ASSERT_NOT_REACHED(); 190 } 191 putQuery.bindText(4, value->toWireString()); 192 if (existingValue) 193 putQuery.bindInt(5, getQuery.getColumnInt(0)); 194 else 195 putQuery.bindInt64(5, m_id); 196 197 ok = putQuery.step() == SQLResultDone; 198 ASSERT_UNUSED(ok, ok); // FIXME: Better error handling? 198 // Before this point, don't do any mutation. After this point, don't error out. 199 200 int64_t dataRowId = isExistingValue ? getQuery.getColumnInt(0) : -1; 201 putObjectStoreData(sqliteDatabase(), key.get(), value.get(), m_id, &dataRowId); 202 203 int i = 0; 204 for (IndexMap::iterator it = m_indexes.begin(); it != m_indexes.end(); ++it, ++i) 205 putIndexData(sqliteDatabase(), indexKeys[i].get(), it->second->id(), dataRowId); 199 206 200 207 callbacks->onSuccess(key.get()); … … 203 210 void IDBObjectStoreBackendImpl::remove(PassRefPtr<IDBKey> key, PassRefPtr<IDBCallbacks> callbacks) 204 211 { 205 SQLiteStatement query(sqliteDatabase(), "DELETE FROM ObjectStoreData " + whereClause(key ->type()));212 SQLiteStatement query(sqliteDatabase(), "DELETE FROM ObjectStoreData " + whereClause(key.get())); 206 213 bool ok = query.prepare() == SQLResultOk; 207 214 ASSERT_UNUSED(ok, ok); // FIXME: Better error handling? … … 234 241 int64_t id = sqliteDatabase().lastInsertRowID(); 235 242 236 RefPtr<IDBIndexBackendI nterface> index = IDBIndexBackendImpl::create(this, id, name, keyPath, unique);243 RefPtr<IDBIndexBackendImpl> index = IDBIndexBackendImpl::create(this, id, name, keyPath, unique); 237 244 ASSERT(index->name() == name); 238 245 m_indexes.set(name, index); 239 callbacks->onSuccess(index. release());246 callbacks->onSuccess(index.get()); 240 247 } 241 248 … … 245 252 } 246 253 254 static void doDelete(SQLiteDatabase& db, const char* sql, int64_t id) 255 { 256 SQLiteStatement deleteQuery(db, sql); 257 bool ok = deleteQuery.prepare() == SQLResultOk; 258 ASSERT_UNUSED(ok, ok); // FIXME: Better error handling. 259 deleteQuery.bindInt64(1, id); 260 ok = deleteQuery.step() == SQLResultDone; 261 ASSERT_UNUSED(ok, ok); // FIXME: Better error handling. 262 } 263 247 264 void IDBObjectStoreBackendImpl::removeIndex(const String& name, PassRefPtr<IDBCallbacks> callbacks) 248 265 { 249 if (!m_indexes.contains(name)) { 266 RefPtr<IDBIndexBackendImpl> index = m_indexes.get(name); 267 if (!index) { 250 268 callbacks->onError(IDBDatabaseError::create(IDBDatabaseException::NOT_FOUND_ERR, "Index name does not exist.")); 251 269 return; 252 270 } 253 271 254 SQLiteStatement deleteQuery(sqliteDatabase(), "DELETE FROM Indexes WHERE name = ? AND objectStoreId = ?"); 255 bool ok = deleteQuery.prepare() == SQLResultOk; 256 ASSERT_UNUSED(ok, ok); // FIXME: Better error handling. 257 deleteQuery.bindText(1, name); 258 deleteQuery.bindInt64(2, m_id); 259 ok = deleteQuery.step() == SQLResultDone; 260 ASSERT_UNUSED(ok, ok); // FIXME: Better error handling. 261 262 // FIXME: Delete index data as well. 272 SQLiteTransaction transaction(sqliteDatabase()); 273 transaction.begin(); 274 doDelete(sqliteDatabase(), "DELETE FROM Indexes WHERE id = ?", index->id()); 275 doDelete(sqliteDatabase(), "DELETE FROM IndexData WHERE indexId = ?", index->id()); 276 transaction.commit(); 263 277 264 278 m_indexes.remove(name); … … 338 352 int currentColumn = 1; 339 353 if (range->flags() & IDBKeyRange::LEFT_BOUND || range->flags() == IDBKeyRange::SINGLE) 340 currentColumn += bindKey(*query, currentColumn, range->left().get());354 currentColumn += range->left()->bind(*query, currentColumn); 341 355 if (range->flags() & IDBKeyRange::RIGHT_BOUND || range->flags() == IDBKeyRange::SINGLE) 342 currentColumn += bindKey(*query, currentColumn, range->right().get());356 currentColumn += range->right()->bind(*query, currentColumn); 343 357 query->bindInt64(currentColumn, m_id); 344 358 -
trunk/WebCore/storage/IDBObjectStoreBackendImpl.h
r65902 r66820 36 36 37 37 class IDBDatabaseBackendImpl; 38 class IDBIndexBackendImpl; 38 39 class SQLiteDatabase; 39 40 … … 76 77 bool m_autoIncrement; 77 78 78 typedef HashMap<String, RefPtr<IDBIndexBackendI nterface> > IndexMap;79 typedef HashMap<String, RefPtr<IDBIndexBackendImpl> > IndexMap; 79 80 IndexMap m_indexes; 80 81 }; -
trunk/WebKit/chromium/ChangeLog
r66818 r66820 1 2010-08-26 Jeremy Orlow <jorlow@chromium.org> 2 3 Reviewed by Steve Block. 4 5 Add index insertion support to IndexedDB. 6 https://bugs.webkit.org/show_bug.cgi?id=44695 7 8 Add asserts on the [] operator. 9 10 * public/WebVector.h: 11 (WebKit::WebVector::operator[]): 12 1 13 2010-09-06 Anton Muhin <antonm@chromium.org> 2 14 -
trunk/WebKit/chromium/public/WebVector.h
r52255 r66820 116 116 bool isEmpty() const { return !m_size; } 117 117 118 T& operator[](size_t i) { return m_ptr[i]; } 119 const T& operator[](size_t i) const { return m_ptr[i]; } 118 T& operator[](size_t i) 119 { 120 WEBKIT_ASSERT(i < m_size); 121 return m_ptr[i]; 122 } 123 const T& operator[](size_t i) const 124 { 125 WEBKIT_ASSERT(i < m_size); 126 return m_ptr[i]; 127 } 120 128 121 129 T* data() { return m_ptr; }
Note: See TracChangeset
for help on using the changeset viewer.